While trying to run the spring boot application (with multi release jar) against different versions of java [java 8 (default) and java 11]
The project is running fine when ran with Java 8. However, upon running the application with java 11 getting ClassNotFoundException
The Project Structure:
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.5</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<start.class>com.example.demo.DemoApplication</start.class>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.inq</groupId>
<artifactId>touchsocial-stress-testing</artifactId>
<version>4.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-toolchains-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<toolchains>
<jdk>
<version>zulu-11</version>
</jdk>
</toolchains>
</configuration>
<executions>
<execution>
<goals>
<goal>toolchain</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<executions>
<execution>
<id>default-compile</id>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<release>8</release>
</configuration>
</execution>
<execution>
<id>compile-java-11</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<release>11</release>
<compileSourceRoots>
<compileSourceRoot>${project.basedir}/src/main/java</compileSourceRoot>
</compileSourceRoots>
<multiReleaseOutput>true</multiReleaseOutput>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifestEntries>
<Multi-Release>true</Multi-Release>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>${start.class}</mainClass>
</configuration>
</plugin>
</plugins>
</build>
after adding the <start-class> mentioned in
for java 8 (java_home), everything seems fine
Note: For POC purpose the contents of both the DemoApplication.java is exactly the same
CodePudding user response:
Your Maven configuration is packaging your multi-release classes in the root of the jar. This means that they're loaded by the system class loader. The system class loader cannot see any of the dependencies packaged in BOOT-INF/lib
so SpringApplication
cannot be loaded.
You need to configure your app to package the multi-release classes beneath BOOT-INF/classes
. One way to do that is to configure the compile task's output directory:
<execution>
<id>compile-java-11</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<release>11</release>
<compileSourceRoots>
<compileSourceRoot>${project.basedir}/src/main/java</compileSourceRoot>
</compileSourceRoots>
<outputDirectory>${project.build.outputDirectory}/BOOT-INF/classes/</outputDirectory>
<multiReleaseOutput>true</multiReleaseOutput>
</configuration>
</execution>
If you do a clean build after making this change, the Java 11-specific class will now be packaged beneath BOOT-INF/classes/META-INF/versions/11/
. As a result, it'll be loaded by Spring Boot's class loader and will be able to access classes from the jars packaged in BOOT-INF/lib
.
This feels like something that Spring Boot's Maven plugin should take care of for you. I've opened https://github.com/spring-projects/spring-boot/issues/28234.