【问题标题】:How to fix “unsupported class file major version 60” in tomcat9?如何修复tomcat9中“不支持的类文件主要版本60”?
【发布时间】:2021-11-25 11:50:43
【问题描述】:

我有一个 Maven 项目。它是用 Java 16 编写的。我安装了 Java 16 JDK。

当我使用 dockerfile 构建它时,一切正常,但是当我运行 docker 并继续我的项目 url 时,我得到一个“不支持的类文件主要版本 60”。

是否可以在 tomcat 或其他东西上运行 java 16 项目?

这是我的一些文件:

Docker 文件:

FROM maven:3.8.1-openjdk-17 as builder
RUN mkdir -p /root/.m2 && mkdir /root/.m2/repository
COPY . /app/
RUN cd /app && mvn clean package -Dmaven.test.skip=true

FROM tomcat:9.0-jdk16-openjdk
COPY --from=builder /app/target/demo.war /usr/local/tomcat/webapps
ENV CATALINA_OPTS=""
EXPOSE 8080
CMD ["catalina.sh", "run"]

还有我的 pom.xml:

<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 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.demo</groupId>
    <artifactId>demo</artifactId>
    <packaging>war</packaging>
    <version>0.0.1</version>
    <name>demo</name>
    <url>http://maven.apache.org</url>

    <properties>
        <!-- Dependencies properties -->
            <!-- ... -->
        <!-- Project build properties -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>16</maven.compiler.source>
        <maven.compiler.target>16</maven.compiler.target>
        <maven-dependency-plugin.version>3.1.1</maven-dependency-plugin.version>
        <maven.resources.plugin>3.0.1</maven.resources.plugin>
        <maven-war-plugin.version>3.2.2</maven-war-plugin.version>
        <java.version>16</java.version>
    </properties>

    <dependencies>
        <!-- ... -->
    </dependencies>
    <build>
        <finalName>demo</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <release>${java.version}</release>
                    <source>${maven.compiler.source}</source>
                    <target>${maven.compiler.target}</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.0.0-M5</version>
            </plugin>
            <!-- ... -->
        </plugins>
    </build>
</project>

Tomcat 日志:

Type Rapport d'exception

message Servlet.init() for servlet [demo-serlvet] threw exception

description Le serveur a rencontré une erreur interne qui l'a empêché de satisfaire la requête.

exception

javax.servlet.ServletException: Servlet.init() for servlet [demo-serlvet] threw exception
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
    org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382)
    org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
    org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893)
    org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1723)
    org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
    java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
    org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    java.base/java.lang.Thread.run(Thread.java:831)
cause mère

java.lang.IllegalArgumentException: Unsupported class file major version 60
    jersey.repackaged.org.objectweb.asm.ClassReader.<init>(ClassReader.java:201)
    jersey.repackaged.org.objectweb.asm.ClassReader.<init>(ClassReader.java:179)
    jersey.repackaged.org.objectweb.asm.ClassReader.<init>(ClassReader.java:165)
    jersey.repackaged.org.objectweb.asm.ClassReader.<init>(ClassReader.java:289)
    org.glassfish.jersey.server.internal.scanning.AnnotationAcceptingListener.process(AnnotationAcceptingListener.java:148)
    org.glassfish.jersey.server.ResourceConfig.scanClasses(ResourceConfig.java:888)
    org.glassfish.jersey.server.ResourceConfig._getClasses(ResourceConfig.java:842)
    org.glassfish.jersey.server.ResourceConfig.getClasses(ResourceConfig.java:751)
    org.glassfish.jersey.server.ResourceConfig$RuntimeConfig.<init>(ResourceConfig.java:1178)
    org.glassfish.jersey.server.ResourceConfig$RuntimeConfig.<init>(ResourceConfig.java:1151)
    org.glassfish.jersey.server.ResourceConfig.createRuntimeConfig(ResourceConfig.java:1147)
    org.glassfish.jersey.server.ApplicationHandler$RuntimeConfigConfigurator.init(ApplicationHandler.java:182)
    org.glassfish.jersey.server.ApplicationHandler.lambda$initialize$0(ApplicationHandler.java:290)
    java.base/java.util.Arrays$ArrayList.forEach(Arrays.java:4203)
    org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:290)
    org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:259)
    org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.java:311)
    org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:154)
    org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:346)
    javax.servlet.GenericServlet.init(GenericServlet.java:158)
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
    org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382)
    org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
    org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893)
    org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1723)
    org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
    java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
    org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    java.base/java.lang.Thread.run(Thread.java:831)
note La trace complète de la cause mère de cette erreur est disponible dans les fichiers journaux de ce serveur.

在 docker exec 之后从 api 容器记录:

root@df012b95a989:/usr/local/tomcat# java -version
openjdk version "16.0.2" 2021-07-20
OpenJDK Runtime Environment (build 16.0.2+7-67)
OpenJDK 64-Bit Server VM (build 16.0.2+7-67, mixed mode, sharing)

【问题讨论】:

  • 你能提供完整的堆栈跟踪吗?
  • 但是当我运行 docker 并继续我的项目 url 时,我得到一个“不支持的类文件主要版本 60”。它将运行低于 1.16 的版本。检查java -version 为您提供的内容,然后更改您的 PATH 以便 >= 1.16 在其中
  • 问题似乎是 The Jersey 库(或者特别是:它包含的 ASM 版本):Maven 和 Tomcat 都适用于 Java 16,但该库不支持 Java 16。通常是 Java库往往是向上兼容的(即不需要额外的支持),但由于 ASM 尝试直接读取和解释类文件,因此需要完全更新才能使用在以后的 JDK 上编译的类。尝试最新版本首先是您的 Jersey 主要版本,如果这不起作用,您可能需要提交错误和/或使用更新的 ASM 版本自行构建。
  • This PR 应该可以解决这个问题,但我不知道它是否已经发布,如果是在哪个版本中发布。
  • @JoachimSauer:2.33 版已经支持 Java 16(参见source code)。

标签: java docker maven tomcat java-16


【解决方案1】:

正如Joachim 在 cmets 中已经指出的那样,您的问题是由 Jersey 打包的 ASM 版本引起的。关于 Spring,它类似于 this question

查找 ASM 支持的 Java 最高版本的最简单方法是查看源代码:

  • Jersey 2.35 最高支持 Java 18,
  • Jersey 2.34 最高支持 Java 17(参见source code),
  • Jersey 2.33 最高支持 Java 16,
  • Jersey 2.30 最高支持 Java 15(带有 Java 15 警告),
  • Jersey 2.29 最高支持 Java 14(带有 Java 14 警告),
  • Jersey 2.28(第一个 EE4j 版本)最高支持 Java 12。

至于 3.x 分支,所有版本都支持 Java 16,而最新的(3.0.2)也支持即将到来的 Java 17。

【讨论】:

  • 非常感谢,我将球衣版本升级到 2.34,它正在工作 \o/。你是我的超级英雄!
猜你喜欢
  • 2021-07-08
  • 1970-01-01
  • 1970-01-01
  • 2021-08-31
  • 2019-09-19
  • 1970-01-01
  • 2022-11-08
  • 2019-07-27
相关资源
最近更新 更多