I have a Java-17 project using Spring Boot which I'm trying to modularize. To take full advantage of the modularization, I'm porting it to Spring Boot 3 milestone 4 and Spring 6 milestone 5.
The project is managed my Maven. I was able to get the project to compile. However, it fails to execute the standard contextLoads() test as generated by Spring Boot. The specific error message is:
[main] DEBUG org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Could not load default TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener]. Specify custom listener classes or make the default listener classes available.
java.lang.NoClassDefFoundError: jakarta/servlet/ServletContext
This error message is repeated twice more with different TestExecutionListener implementations, namely TransactionalTestExecutionListener and SqlScriptsTestExecutionListener, but Spring ultimately loads a number of TestExecutionListeners and tries to execute the test. However, the test fails:
java.lang.NoClassDefFoundError: org/springframework/beans/factory/aot/BeanFactoryInitializationAotProcessor
[...series of java.base frames...]
at spring.context@6.0.0-M5/org.springframework.context.annotation.AnnotationConfigUtils.registerAnnotationConfigProcessors(AnnotationConfigUtils.java:165)
at spring.context@6.0.0-M5/org.springframework.context.annotation.AnnotationConfigUtils.registerAnnotationConfigProcessors(AnnotationConfigUtils.java:138)
at spring.context@6.0.0-M5/org.springframework.context.annotation.AnnotatedBeanDefinitionReader.<init>(AnnotatedBeanDefinitionReader.java:88)
at spring.context@6.0.0-M5/org.springframework.context.annotation.AnnotatedBeanDefinitionReader.<init>(AnnotatedBeanDefinitionReader.java:71)
at spring.context@6.0.0-M5/org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:69)
at spring.boot@3.0.0-M4/org.springframework.boot.ApplicationContextFactory.lambda$static$0(ApplicationContextFactory.java:55)
at org.springframework.boot.test.context.SpringBootContextLoader.lambda$loadContext$1(SpringBootContextLoader.java:120)
at spring.boot@3.0.0-M4/org.springframework.boot.SpringApplication.createApplicationContext(SpringApplication.java:566)
at spring.boot@3.0.0-M4/org.springframework.boot.SpringApplication.run(SpringApplication.java:309)
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:132)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:123)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:124)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:118)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
at org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener.prepareTestInstance(SpringBootDependencyInjectionTestExecutionListener.java:43)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:248)
at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:138)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$8(ClassBasedTestDescriptor.java:363)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.executeAndMaskThrowable(ClassBasedTestDescriptor.java:368)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$9(ClassBasedTestDescriptor.java:363)
[...many more frames, mostly from junit and surefire...]
Caused by: java.lang.ClassNotFoundException: org.springframework.beans.factory.aot.BeanFactoryInitializationAotProcessor
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
This problem is probably caused by some error in my module-info.java. The Spring modules I'm using are:
requires spring.beans;
requires spring.context;
requires spring.boot.autoconfigure;
requires spring.core;
requires spring.boot;
requires spring.oxm;
requires spring.web;
requires spring.ws.core;
[...]
opens [my module] to spring.core;
exports [my module] to spring.beans, spring.context;
What am I missing? The application compiles and works fine with Spring 5.3 / Spring Boot 2.7, but I need to modularize it to be able to create an installer.