首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用java 11运行spring启动多版本jar时的ClassNotFoundException

使用java 11运行spring启动多版本jar时的ClassNotFoundException
EN

Stack Overflow用户
提问于 2021-10-07 09:27:50
回答 1查看 293关注 0票数 2

在尝试针对java 8(默认)和java 11的不同版本运行spring引导应用程序(带有多版本jar)时

当使用Java 8运行时,该项目运行良好。

项目结构:

pom.xml

代码语言:javascript
复制
<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>

添加this answer中提到的内容之后,构建就成功了

但是,在java 11上运行jar获取ClassNotFoundException

对于java 8 (java_home)来说,一切似乎都很好

注意:就POC而言,两个DemoApplication.java的内容完全相同。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-10-07 11:02:20

您的Maven配置正在将您的多版本类打包到jar的根中。这意味着它们由系统类加载器加载。系统类加载器无法看到BOOT-INF/lib中打包的任何依赖项,因此无法加载SpringApplication

您需要配置您的应用程序来打包BOOT-INF/classes下面的多版本类。这样做的一种方法是配置编译任务的输出目录:

代码语言:javascript
复制
<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>

如果您在进行此更改后进行了干净的构建,那么Java11特定的类现在将打包在BOOT-INF/classes/META-INF/versions/11/下面。因此,它将由Spring的类加载器加载,并且能够从打包在BOOT-INF/lib中的jars访问类。

这就像是Spring的Maven插件应该为您解决的问题。我开了https://github.com/spring-projects/spring-boot/issues/28234

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69478693

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档