-
Notifications
You must be signed in to change notification settings - Fork 35
RFC: Classloading in Vert.x 4
Proposal from community made by Pascal.
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.
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.
-
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.
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.
The current logic for creating an isolated class loader is the following:
-
Create new IsolatedClassLoader
-
Copy classpath urls from system class loader to new IsolatedClassLoader
-
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].
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);
...
}