Skip to content

RFC: Classloading in Vert.x 4

Julien Viet edited this page Sep 19, 2019 · 1 revision

Classloading in Vert.x 4.0 RFC

Proposal from community made by Pascal.

Intro

Vert.x is supporting deployment options like isolatingGroups, isolatedClasses and extraClassPaths. Providing these functionality requires that only Vert.x controls the class loader, to ensure that no other process is manipulating the class loader. I guess this is the reason why the class loader is generated inside the DeploymentManager [1] and no place is offered to modify it.

Problem

The current implementation [2] of this feature is not supporting Java 9+, due to the change of the system class loader which is not longer instance of URLClassLoader.

Goals

  • Deploy verticles in an isolated/custom class loader in Java 9+.

  • Verticles should be able to load classes with the same class loader which has created the verticle.

Proposals

The following proposals would solve the goal mentioned above. The first one is less invasive and tries to transport the existing logic to Java 9+ as good as possible. The second one will need a breaking change in the API, but empowers developers to use a customized class loader which exactly fits to their needs.

Proposal 1: Transport current logic to Java 9+

The current logic for creating an isolated class loader is the following:

  1. Create new IsolatedClassLoader

  2. Copy classpath urls from system class loader to new IsolatedClassLoader

  3. Add classpath urls from extraClassPaths option to new IsolatedClassLoader

The problem is, that in Java 9+ it is not possible to call getURLs() on the system class loader. Because of this, we have to find a workaround to get the urls. A workaround e.g. is the fix which was introduced in the 3.7 [3].

Proposal 2: Pass custom class loader as deployment option

The idea of this approach is, that a developer prepares an own class loader and passes this class loader to the deployVerticle method. Of course this would make the deployment options isolatingGroups, isolatedClasses and extraClassPaths obsolete and they could be removed. this would also simplify the whole deployment logic.

Note
Just using the deployVerticle with the Supplier signature would not work, because if the deployd verticle tries to instantiate a new class, the system class loader would be used to load this class.

The original code of the two examples below could be find here [4] for the first one, and here [5] for the second one.

public void deployVerticle(Supplier<Verticle> verticleSupplier,
                           DeploymentOptions options,
                           Classloader classloader,
                           Handler<AsyncResult<String>> completionHandler) {
   ...
   ClassLoader cl = classloader != null ? classloader : getClassLoader(options);
   ...
}
public void deployVerticle(String identifier,
                           DeploymentOptions options,
                           Classloader classloader,
                           Handler<AsyncResult<String>> completionHandler) {
   ...
   ClassLoader cl = classloader != null ? classloader : getClassLoader(options);
   ...
}
Clone this wiki locally