-
Notifications
You must be signed in to change notification settings - Fork 41.2k
Asynchronous deserialization performed by Hazelcast may fail due to the wrong ClassLoader being used #24836
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
Comments
I assume that Unfortunately, the JDK's common fork-join pool uses the app class loader as its TCCL. This makes it unsuitable for use in a packaged Boot application and, I suspect, in any environment with a custom class loader such as a Servlet container. We've seen this problem before (#15737) and, in general terms, I don't think we can do anything about it. In this specific case, it looks like the auto-configuration could be improved by setting the class loader automatically (assuming that's possible while still honouring the rest of the user's configuration). |
Hmm. I think maybe there is still something in Hazelcast which we could ask them to fix. This app works fine (IDE and JAR) when Hazelcast is not on the classpath: @SpringBootApplication
public class IssueApplication {
public static void main(String[] args) {
SpringApplication.run(IssueApplication.class, args);
}
@Bean
CommandLineRunner runner() {
return args -> {
ForkJoinPool.commonPool().submit(() -> {
System.err.println(ClassUtils.resolveClassName(Foo.class.getName(), null));
}).get();
};
}
}
... and then it fails from a JAR if you just put Hazelcast on the classpath but never use it:
Adding Hazelcast to the classpath (and an empty |
That's odd. The common pool uses |
This is even weirder. If you have a 2 node cluster it doesn't fail from the JAR. It only fails with one node. |
That's rubbish, sorry. Brain fart probably. It always fails from the JAR for the reason you said (the system class loader is the wrong one). UPDATE: it sometimes fails. Especially with Java 8 (as opposed to 11, where |
So maybe we need to set the class loader in Hazelcast |
Yep, I think so. Now we need to figure out how to do that across all the various configuration options that we support. |
I think they all end up in a |
I discovered this in a long yak-shaving session migrating an app to Boot 2.4.1 and Hazelcast 4.0.3.
This fails when you run it from the jar:
It's fine when you run in an IDE, or with
java -classpath ...
. The problem is that Hazelcast uses theThread.crrentThread().getContextClassLoader()
by default, and in the async background thread this is theJarLauncher
not theAppClassLoader
.I worked around it with this
but the issue is more generic really - probably any library that uses JDK fork-join utilities will end up with the same class loader.
The text was updated successfully, but these errors were encountered: