Search code examples
javaspringjava-platform-module-system

How to get Spring boot project work with JPMS?


I'm trying to set up a modular spring application. I have a very basic one, generated by start.spring.io. Only thing I did is added module-info.java file, which looks like this:

open module modules {
    requires spring.boot;
    requires spring.boot.autoconfigure;
    requires spring.beans;
    requires spring.context;
}

It compiles, shows no errors in IntelliJ. When I run it it throws exceptions. Console looks like this:

java.lang.IllegalStateException: Unable to load cache item
    at org.springframework.cglib.core.internal.LoadingCache.createEntry(LoadingCache.java:79) ~[spring-core-5.3.23.jar:5.3.23]
    at org.springframework.cglib.core.internal.LoadingCache.get(LoadingCache.java:34) ~[spring-core-5.3.23.jar:5.3.23]
    at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator.java:134) ~[spring-core-5.3.23.jar:5.3.23]
    at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:319) ~[spring-core-5.3.23.jar:5.3.23]
    at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:572) ~[spring-core-5.3.23.jar:5.3.23]
    at org.springframework.cglib.proxy.Enhancer.createClass(Enhancer.java:419) ~[spring-core-5.3.23.jar:5.3.23]
    at [email protected]/org.springframework.context.annotation.ConfigurationClassEnhancer.createClass(ConfigurationClassEnhancer.java:137) ~[spring-context-5.3.23.jar:na]
    at [email protected]/org.springframework.context.annotation.ConfigurationClassEnhancer.enhance(ConfigurationClassEnhancer.java:109) ~[spring-context-5.3.23.jar:na]
    at [email protected]/org.springframework.context.annotation.ConfigurationClassPostProcessor.enhanceConfigurationClasses(ConfigurationClassPostProcessor.java:447) ~[spring-context-5.3.23.jar:na]
    at [email protected]/org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanFactory(ConfigurationClassPostProcessor.java:268) ~[spring-context-5.3.23.jar:na]
    at [email protected]/org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:325) ~[spring-context-5.3.23.jar:na]
    at [email protected]/org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:147) ~[spring-context-5.3.23.jar:na]
    at [email protected]/org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:746) ~[spring-context-5.3.23.jar:na]
    at [email protected]/org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:564) ~[spring-context-5.3.23.jar:na]
    at [email protected]/org.springframework.boot.SpringApplication.refresh(SpringApplication.java:734) ~[spring-boot-2.7.5.jar:na]
    at [email protected]/org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) ~[spring-boot-2.7.5.jar:na]
    at [email protected]/org.springframework.boot.SpringApplication.run(SpringApplication.java:308) ~[spring-boot-2.7.5.jar:na]
    at [email protected]/org.springframework.boot.SpringApplication.run(SpringApplication.java:1306) ~[spring-boot-2.7.5.jar:na]
    at [email protected]/org.springframework.boot.SpringApplication.run(SpringApplication.java:1295) ~[spring-boot-2.7.5.jar:na]
    at [email protected]/com.example.modules.ModulesApplication.main(ModulesApplication.java:10) ~[classes/:na]
Caused by: java.lang.IllegalAccessError: class com.example.modules.ModulesApplication$$EnhancerBySpringCGLIB$$91c2c32e (in module modules) cannot access class org.springframework.cglib.core.ReflectUtils (in unnamed module @0x3bd40a57) because module modules does not read unnamed module @0x3bd40a57
    at [email protected]/com.example.modules.ModulesApplication$$EnhancerBySpringCGLIB$$91c2c32e.CGLIB$STATICHOOK1(<generated>) ~[classes/:na]
    at [email protected]/com.example.modules.ModulesApplication$$EnhancerBySpringCGLIB$$91c2c32e.<clinit>(<generated>) ~[classes/:na]
    at java.base/java.lang.Class.forName0(Native Method) ~[na:na]
    at java.base/java.lang.Class.forName(Class.java:467) ~[na:na]
    at org.springframework.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:602) ~[spring-core-5.3.23.jar:5.3.23]
    at org.springframework.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:363) ~[spring-core-5.3.23.jar:5.3.23]
    at org.springframework.cglib.proxy.Enhancer.generate(Enhancer.java:585) ~[spring-core-5.3.23.jar:5.3.23]
    at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:110) ~[spring-core-5.3.23.jar:5.3.23]
    at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:108) ~[spring-core-5.3.23.jar:5.3.23]
    at org.springframework.cglib.core.internal.LoadingCache$2.call(LoadingCache.java:54) ~[spring-core-5.3.23.jar:5.3.23]
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[na:na]
    at org.springframework.cglib.core.internal.LoadingCache.createEntry(LoadingCache.java:61) ~[spring-core-5.3.23.jar:5.3.23]
    ... 19 common frames omitted

I can't figure out which more modules should I require. I've tried adding some JVM arguments but it didn't help at all.


Solution

  • Java Modules (JPMS) do not allow the use of reflection without opening the appropriate package to the module using reflection.

    The "Caused by:" line in the stack trace shows the illegal access:

    class com.example.modules.ModulesApplication$$EnhancerBySpringCGLIB$$91c2c32e (in module modules) cannot access class org.springframework.cglib.core.ReflectUtils (in unnamed module @0x3bd40a57) because module modules does not read unnamed module @0x3bd40a57

    Since the package org.springframework.cglib.core does not have a module descriptor it is in the "unnamed module" which is not "open" to reflection.

    You can fix this by adding the following VM argument (either on the command line or your IDE's run configuration) to allow the modules module to read the unnamed module:

    --add-reads modules=ALL-UNNAMED