dockerBuild 失败导致 unsupported class file major version 61 错误

dockerBuild fails resulting in an unsupported class file major version 61 error

我正在尝试构建一个 docker 图像,但我收到一条错误消息,告诉我 jib-maven-plugin 失败。导致不支持的 class 文件主要版本 61 错误。

起初我以为这与我使用的 java 版本有关 (Java 17)。所以我从我的机器上卸载了它并安装了 Java 15 但没有成功。

我正在尝试的命令 运行:

./mvnw compile jib:dockerBuild -Djib.to.image=fullstack:v1

我得到的错误响应:

Failed to execute goal com.google.cloud.tools:jib-maven-plugin:2.5.2:dockerBuild (default-cli) on project demo: Execution default-cli of goal com.google.cloud.tools:jib-maven-plugin:2.5.2:dockerBuild failed: Unsupported class file major version 61 -> [Help 1]

我的 pom.xml 文件:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </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>15</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
            <!-- The plugin below is to make a docker image using Jib -->
            <plugin>
                <groupId>com.google.cloud.tools</groupId>
                <artifactId>jib-maven-plugin</artifactId>
                <version>2.5.2</version>
                <configuration>
                    <from>
                        <image>openjdk:15</image>
                    </from>
                    <container>
                        <ports>
                            <port>8080</port>
                        </ports>
                        <format>OCI</format>
                    </container>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <!-- The code below is for packaging the frontend with the backend using maven -->
    <profiles>
        <profile>
            <id>build-frontend</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <build>
                <plugins>

                    <plugin>
                        <groupId>com.github.eirslett</groupId>
                        <artifactId>frontend-maven-plugin</artifactId>
                        <!-- Use the latest released version:
                                  https://repo1.maven.org/maven2/com/github/eirslett/frontend-maven-plugin/ -->
                        <version>1.11.2</version>
                        <configuration>
                            <nodeVersion>v4.6.0</nodeVersion>
                            <workingDirectory>src/frontend</workingDirectory>
                        </configuration>
                        <executions>
                            <execution>
                                <id>install node and npm</id>
                                <goals>
                                    <goal>install-node-and-npm</goal>
                                </goals>
                                <configuration>
                                    <nodeVersion>v15.4.0</nodeVersion>
                                    <npmVersion>7.3.0</npmVersion>
                                </configuration>
                            </execution>
                            <execution>
                                <id>npm install</id>
                                <goals>
                                    <goal>npm</goal>
                                </goals>
                                <configuration>
                                    <arguments>install</arguments>
                                </configuration>
                            </execution>
                            <execution>
                                <id>npm run build</id>
                                <goals>
                                    <goal>npm</goal>
                                </goals>
                                <configuration>
                                    <arguments>run build</arguments>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                    <!-- The plugin below is for copying the build folder into the target static folder (maven) -->
                    <plugin>
                        <artifactId>maven-resources-plugin</artifactId>
                        <executions>
                            <execution>
                                <id>copy-build-folder</id>
                                <phase>process-classes</phase>
                                <goals>
                                    <goal>copy-resources</goal>
                                </goals>
                                <configuration>
                                    <resources>
                                        <resource>
                                            <directory>src/frontend/build</directory>
                                        </resource>

                                    </resources>
                                    <outputDirectory>${basedir}/target/classes/static</outputDirectory>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>

</project>

更新(01/20/2022):发布了修复了错误的新 Jib 版本。升级 Jib 将修复它。

然而,几年后当你使用Java 18+左右时,你可能会再次遇到这个问题。尽管如此,还是有解决方法。


基本上,这是 Jib 中的 bug

Jib 使用 ASM 库检查已编译的 Java 字节码以自动推断出一个主要的 class(即定义 public static void main() 的字节码)。这样,如果您只有一个这样的 class,Jib 可以自动推断并使用那个 class 作为图像入口点。

这种情况的原因是,Jib 目前没有使用能够识别和理解较新 Java 版本的字节码的最新 ASM 库。 Jib 团队需要升级库并制作新的 Jib 版本。

解决方法:为了防止 Jib 进行自动推理,您可以通过 <container><mainClass> 手动设置所需的主要 class,例如,<container><mainClass>com.example.your.Main</mainClass>.与其他 Jib 参数一样,这可以通过属性或命令行设置,例如 -Dcontainer.mainClass=....


请注意,虽然在本例中错误是由于 ASM 引起的,但当然也可能由于其他原因而出现此错误。您可能希望 运行 Maven 与 -e-X 获取完整的堆栈跟踪以查看错误的来源。