ServiceLoader.load(Class, ClassLoader) does not load services exposed in modules and loaded by parent CL

Alan Bateman Alan.Bateman at oracle.com
Thu May 24 10:29:33 UTC 2018


On 23/05/2018 21:28, Peter Levart wrote:
> :
>
> It's not an official plugin. And it seems that the Maven container is 
> to blame, not the plugin. 
Robert Scholte is on this mailing list and may be able to comment on this.


> The nonstandard ClassLoader is supplied by the container. The plugin 
> just uses the most direct and default API possible to instantiate 
> JavaScript engine:
>
> jsEngine = new ScriptEngineManager().getEngineByName("JavaScript");
>
> It is the environment the plugin is executing in that doesn't play 
> well with how system service providers are located from JDK 9 on - 
> namely, the nonstandard ClassLoader that delegates to system class 
> loader, but does not express this also in the .getParent() result. I 
> don't know why Maven choose this, but closer inspection reveals that 
> its ClassLoader does have a "parent", but it keeps it in its own field 
> called "parentClassLoader" and doesn't return it from .getParent(). 
> There must be a reason for this, but I don't know that it is.
>
> Do other parts of the JDK also use TCCL to bootstrap service lookup by 
> default? Isn't it unusual that ScriptEngineManager uses TCCL by default?
I wasn't involved in JSR 223 but it may have envisaged scenarios where 
applications bundle scripting language implementations. This is not too 
unusual and you'll find several APIs do this to allow for cases where an 
application is launched in a container environment. Legacy applet and 
Java EE containers have historically created a class loader per 
"application" and this becomes the TCCL for the threads in that application.

-Alan


More information about the core-libs-dev mailing list