[英]ClassNotFoundException while running a Spring Boot application
[英]ClassNotFoundException while running spring boot multi release jar with java 11
尝试针对不同版本的 java [java 8(默认)和 java 11] 运行 spring 引导应用程序(带有多版本 jar)时
使用 Java 8 运行时项目运行良好。但是,使用 java 11 运行应用程序时出现 ClassNotFoundException
项目结构:
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>
添加此答案中提到的 <start-class> 后构建成功
但是,在 java 11 上运行 jar 得到 ClassNotFoundException
对于 java 8 (java_home),一切似乎都很好
注意:出于 POC 目的,DemoApplication.java 的内容完全相同
您的 Maven 配置将您的多版本类打包到 jar 的根目录中。这意味着它们由系统 class 加载程序加载。 系统 class 加载器看不到任何打包在BOOT-INF/lib
中的依赖项,因此无法加载SpringApplication
。
您需要将应用配置为 package BOOT-INF/classes
下的多版本类。 一种方法是配置编译任务的 output 目录:
<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>
如果您在进行此更改后进行干净构建,则 Java 11-specific class 现在将打包在BOOT-INF/classes/META-INF/versions/11/
下。 因此,它将由 Spring Boot 的 class 加载程序加载,并将能够访问 jars 中打包在BOOT-INF/lib
中的类。
这感觉像是 Spring Boot 的 Maven 插件应该为您处理的事情。 我打开了 https://github.com/spring-projects/spring-boot/issues/28234 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.