当前位置: 首页 > 知识库问答 >
问题:

使用java 11运行spring boot多版本jar时的ClassNotFoundException

苏季同
2023-03-14

在尝试针对不同版本的java[Java8(默认)和Java11]运行spring boot应用程序(使用Multi-Release jar)时

当用Java8运行时,该项目运行良好。但是,在使用Java11运行应用程序时,将获得ClassNotFoundException

项目结构:

<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>

注意:出于POC的目的,DemoApplication.java的内容完全相同

共有1个答案

危钱明
2023-03-14

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

您需要将应用程序配置为在boot-inf/classes下面打包多版本类。一种方法是配置编译任务的输出目录:

<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特定的类现在将被打包在boot-inf/classes/meta-inf/versions/11/下面。因此,它将由Spring Boot的类加载器加载,并且能够访问boot-inf/lib中打包的JAR中的类。

 类似资料:
  • 问题内容: 我想知道是否有可能在运行时检索该类来自的jar的版本号? 我知道可以找到该类来自的jar: 但是版本呢? (假设其不在文件名中:) 问题答案:

  • 我想知道是否可以在运行时检索类的来源的jar的版本号? 我知道有可能找到类的来源: 但是一个版本呢? (假设它不在文件名中:))

  • 在java 9中,引入了一个新特性,其中jar格式得到了增强,可以根据平台维护和使用不同版本的java类或资源。 在JAR中,文件文件的部分中有一个条目。 目录还包含版本子目录,其子目录(从9开始,用于Java 9)存储版本特定的类和资源文件。 在这个例子中,我们将使用多版本的jar来创建两个版本的文件,一个用于jdk 7,另一个用于jdk 9,并在不同的jdk版本上运行。 第1步 - 创建一个文

  • 我有一个用Java 8编译的可执行jar文件,其中包含一个名为< code>app.jar的JavaFX应用程序。 当我安装了Java8时,我可以简单地用运行它。 现在我只安装了Java 11,运行上面的命令会产生以下错误: 因为Java 11不再包含JavaFX。 所以我考虑安装JavaFX。openjfx.org以两种形式提供JavaFx:SDK和JMOD文件。 我认为我不需要SDK,因为我不

  • 我设法为springboot fat jar构建了本机映像,但当我运行它时,它抛出了异常:“”。我尝试添加一个默认构造和一个空的init()方法,但都失败了。如何克服此异常并使本机映像运行? 以下是完整日志:

  • 如何将jar文件更新到coldFusion安装附带的最新版本?我可以在不同位置看到不同版本的jar文件。如何确认当前正在运行哪个版本的jar以及ColdFusion在哪些位置寻找这些罐子? 例如,在coldfusion\lib中,我有以下jar: commons集合。罐子 commons集合。3.1。罐子 commons集合。3.2。震击器 然后在另一个位置\Coldfusion\cfusion\