-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Region Not Found with Spring Boot due to Java 11 ForkJoinPool ClassLoader
change
#657
Comments
Thank you for reporting this issue.
Having noted the above statement, I am going to make 2 changes to SDG.
With 2, users can set this property in Spring Boot's Given the core Spring Framework, Spring Container's (prior) bean indexing capabilities, and now comprehensive AOT (eventual CrAC and Projet Leydon support) it is not strictly necessary to parallelize the classpath component scan. In fact, by default, it should not. Still, if users need this capability, then it is a simple matter to configure this behavior using the new property from #2 above. |
Fortunately, this fix will go out tomorrow, during our regularly scheduled Spring Data releases. |
… resolution. We now supply the ClassLoader used to resolve GemFire/Geode entities to the Spring ClassPathScanningCandidateComponentProvider allowing entity classes to be resolved in all contexts (e.g. Spring Boot generated JARs). Additionally, SDG now provides configuration via a hidden property (spring.data.gemfire.classpath.scan.parallel) to tune the classpath scanning function (Stream). The default value for parallizing the Stream used during classpath scanning is now false. Closes spring-projects#657
ClassLoader
change
Many thanks John for the rapid turnaround, prolific as ever! EOL notice for SDG is noted. I've benefited from your many detailed stackoverflow explanations over the years and want to say thanks for that too :) |
Thank you for the kind feedback. Wishing you all the best. |
Problem
I found that after upgrading from Java 8 to Java 11, my Spring boot app intermittently (80% of the time) fails to start due to
Debuging ...
So the Repository classes are found but the adjacent Region classes are not. Debuging soon revealed the issue was caused by
@Region
beans not being found by Spring'sClassPathScanningCandidateComponentProvider
. With trace debugging, I found that when the problem occurs 1) the classloader is of type 'jdk.internal.loader.ClassLoaders' and 2)the thread of type 'ForkJoinPool.commonPool-worker'Root Cause
From there I found spring-projects/spring-boot#6626 and https://stackoverflow.com/questions/49113207/completablefuture-forkjoinpool-set-class-loader which advise that
My understanding is that because SpringBoot puts classes in folder BOOT_INF, the Spring classloader is needed to find them.
Line 212 of https://github.com/spring-projects/spring-data-gemfire/blob/main/src/main/java/org/springframework/data/gemfire/config/annotation/support/GemFireComponentClassTypeScanner.java requests that all classes be streamed and loaded in parallel and so the ForkJoinPool will attempt and fail to find the Region classes in the SpringBoot jar.
stream(this.spliterator(), true)
Possible fixes
componentProvider.setResourceLoader(new DefaultResourceLoader(getEntityClassLoader()));
before the return in method newClassPathScanningCandidateComponentProviderstream(this.spliterator(), false)
Notes
In the cases where the app starts, ForkJoinPool is not used at all and the JVM/OS decides to execute the entire stream sequentially using the main thread. I never found that only some of the Regions where loaded.
See also https://stackoverflow.com/questions/72740543/issue-with-spring-boot-gemfire-integration which also describes a problem loading Region beans
The text was updated successfully, but these errors were encountered: