繁体   English   中英

运行时出现 ClassNotFoundException spring 引导多版本 jar 和 java 11

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM