Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use ServiceLoader.load with the current classloader instead of the context classloader #1727

Merged
merged 2 commits into from
May 12, 2021

Conversation

jonenst
Copy link
Contributor

@jonenst jonenst commented May 10, 2021

The context classloader can be the wrong one (and ServiceLoader.load returns an empty list)
when you are calling ServiceLoader.load in the ForkJoinPool.commonPool() (or any other thread pool)
and you have your classes in another classloader than the AppClassLoader (=system classloader).
This is the case when using a springboot fat jar, or when deploying the code in a war in an application
server, or when using mvn exec:java

Signed-off-by: Jon Harper jon.harper87@gmail.com

Please check if the PR fulfills these requirements (please use '[x]' to check the checkboxes, or submit the PR and then click the checkboxes)

  • The commit message follows our guidelines
  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been added / updated (for bug fixes / features)

Does this PR already have an issue describing the problem ? If so, link to this issue using '#XXX' and skip the rest
NO

What kind of change does this PR introduce? (Bug fix, feature, docs update, ...)
Bug Fix

What is the current behavior? (You can also link to an open issue here)
Run an importer (or any other computation that calls ServiceLoader.load()) in the forkjoinpool.commonpool in a war (or in maven exec:java) (or in a springboot fatjar), service loader returns an empty list

What is the new behavior (if this is a feature change)?
works

Does this PR introduce a breaking change or deprecate an API? If yes, check the following:
NO

Other information:

WIP: need to check if we want to use the thread context classloader as a fallback ? Something like

ServiceLoader serviceloader = ServiceLoader.load(X.Class, Y.class.getClassLoader())
if (Y.class.getClassLoader != Thread.getContextClassLoader && !serviceLoader.iterator().hasNext()) {
    ServiceLoader serviceloader = ServiceLoader.load(X.Class) // here it's using Thread.getContextClassLoader()
}

…ntext classloader

The context classloader can be the wrong one (and ServiceLoader.load returns an empty list)
when you are calling ServiceLoader.load in the ForkJoinPool.commonPool() (or any other thread pool)
and you have your classes in another classloader than the AppClassLoader (=system classloader).
This is the case when using a springboot fat jar, or when deploying the code in a war in an application
server, or when using mvn exec:java

Signed-off-by: Jon Harper <jon.harper87@gmail.com>
@jonenst jonenst force-pushed the fixserviceloaderinthreadpools branch from 6466b02 to c514cc2 Compare May 11, 2021 06:50
@jonenst jonenst changed the title use ServiceLoader.load with the current classloader instead of the context classloader [WIP] use ServiceLoader.load with the current classloader instead of the context classloader May 11, 2021
@sonarqubecloud
Copy link

Kudos, SonarCloud Quality Gate passed!

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

80.0% 80.0% Coverage
0.0% 0.0% Duplication

@miovd miovd merged commit f9e5f6f into master May 12, 2021
@miovd miovd deleted the fixserviceloaderinthreadpools branch May 12, 2021 09:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants