Loading providers in named modules with ServiceLoader using a plugin class realm

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Loading providers in named modules with ServiceLoader using a plugin class realm

gboue
Hi,

With the introduction of modules in JDK 9, there were changes with
regard to how classloading works, and this impacts class realms created
in Maven. Today, the parent (as per ClassLoader.getParent()) of a class
realm is null, which represents the bootstrap classloader. In JDK 9, the
change is that some classes were moved to a named module other than
java.base, and they are not loaded with the bootstrap classloader
anymore, but with the platform classloader (which was previously the
extension classloader, see JDK-814637).

This has consequences, like MANTRUN-200, where locating providers with
the ServiceLoader API, using the plugin class realm, will miss JDK
internal implementation classes. In the case of MANTRUN-200, it is
Nashorn of the jdk.scripting.nashorn module, that cannot be found
because of the way ServiceLoader works
http://download.java.net/java/jdk9/docs/api/java/util/ServiceLoader.html#load-java.lang.Class-java.lang.ClassLoader-.
During the search in named modules, the class realm will not be able to
use its strategy since that process relies on parent delegation
implemented as explicit calls to ClassLoader.getParent()
(http://hg.openjdk.java.net/jdk9/jdk9/jdk/file/f3cf7fd26baa/src/java.base/share/classes/java/util/ServiceLoader.java#l1062),
which, for a class realm, corresponds to the base classloader, i.e. the
bootstrap classloader. And since the Nashorn script engine factory was
loaded with the platform classloader, it is missed.

It seems that the fix here would be to make all class realms have as
base classloader the platform classloader starting with JDK 9, instead
of the bootstrap classloader (there is a new utility method in
ClassLoader to obtain the platform classloader). I verified that this
solves the problem described in MANTRUN-200, but before I create an MNG
issue, I'm wondering if this is the correct approach.

What do you think of this change to class realms? The other possibility
I can think of would be to have a way in the JDK to override the search
in named modules, so that our ClassRealm can also delegate to its parent
classloader. It is possible for unnamed modules (since the search
process then relies on the ClassLoader.getResources method, that can be
overriden) but it doesn't look like (and probably intentionally so) to
be possible for named modules.

Guillaume


---
L'absence de virus dans ce courrier électronique a été vérifiée par le logiciel antivirus Avast.
https://www.avast.com/antivirus


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Loading providers in named modules with ServiceLoader using a plugin class realm

rfscholte
Hi Guillaume,

I don't know all the details about the Platform classloader, but it has  
been introduced with a reason.
So I don't think we should switch to it by default. I think the plugin is  
well aware which classloaders / modules it wants to use (it should be), so  
I think we need to find a mechanism for plugins to select their  
classloaders and modules.

thanks,
Robert

On Sun, 25 Jun 2017 17:19:07 +0200, Guillaume Boué <[hidden email]>  
wrote:

> Hi,
>
> With the introduction of modules in JDK 9, there were changes with
> regard to how classloading works, and this impacts class realms created
> in Maven. Today, the parent (as per ClassLoader.getParent()) of a class
> realm is null, which represents the bootstrap classloader. In JDK 9, the
> change is that some classes were moved to a named module other than
> java.base, and they are not loaded with the bootstrap classloader
> anymore, but with the platform classloader (which was previously the
> extension classloader, see JDK-814637).
>
> This has consequences, like MANTRUN-200, where locating providers with
> the ServiceLoader API, using the plugin class realm, will miss JDK
> internal implementation classes. In the case of MANTRUN-200, it is
> Nashorn of the jdk.scripting.nashorn module, that cannot be found
> because of the way ServiceLoader works
> http://download.java.net/java/jdk9/docs/api/java/util/ServiceLoader.html#load-java.lang.Class-java.lang.ClassLoader-.
> During the search in named modules, the class realm will not be able to
> use its strategy since that process relies on parent delegation
> implemented as explicit calls to ClassLoader.getParent()
> (http://hg.openjdk.java.net/jdk9/jdk9/jdk/file/f3cf7fd26baa/src/java.base/share/classes/java/util/ServiceLoader.java#l1062),
> which, for a class realm, corresponds to the base classloader, i.e. the
> bootstrap classloader. And since the Nashorn script engine factory was
> loaded with the platform classloader, it is missed.
>
> It seems that the fix here would be to make all class realms have as
> base classloader the platform classloader starting with JDK 9, instead
> of the bootstrap classloader (there is a new utility method in
> ClassLoader to obtain the platform classloader). I verified that this
> solves the problem described in MANTRUN-200, but before I create an MNG
> issue, I'm wondering if this is the correct approach.
>
> What do you think of this change to class realms? The other possibility
> I can think of would be to have a way in the JDK to override the search
> in named modules, so that our ClassRealm can also delegate to its parent
> classloader. It is possible for unnamed modules (since the search
> process then relies on the ClassLoader.getResources method, that can be
> overriden) but it doesn't look like (and probably intentionally so) to
> be possible for named modules.
>
> Guillaume
>
>
> ---
> L'absence de virus dans ce courrier électronique a été vérifiée par le  
> logiciel antivirus Avast.
> https://www.avast.com/antivirus
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Loading...