1. 概述

本文,我们将了解导致 java.lang.UnsupportedClassVersionError: Unsupported major.minor version 错误的原因及解决方案。

2. 错误日志

Exception in thread "main" java.lang.UnsupportedClassVersionError: com/baeldung/MajorMinorApp 
  has been compiled by a more recent version of the Java Runtime (class file version 55.0), 
  this version of the Java Runtime only recognizes class file versions up to 52.0

这个错误告诉我们,我们的类是用比尝试运行它的 Java 版本更高的版本编译的。通俗的说,比如我们用 Java 11 编译,而运行时使用的却是 Java 8 。

2.1. JDK和Class版本号对应关系

作为参考,我们先了解 Java 版本号之间的对应关系,以便下载正确的Java版本。

主版本号(major)和次版本号(minor),存储在 class 字节码的第6和第7个字节上。

下面是主版本号和Java版本的映射关系

  • 45 = Java 1.1
  • 46 = Java 1.2
  • 47 = Java 1.3
  • 48 = Java 1.4
  • 49 = Java 5
  • 50 = Java 6
  • 51 = Java 7
  • 52 = Java 8
  • 53 = Java 9
  • 54 = Java 10
  • 55 = Java 11
  • 56 = Java 12
  • 57 = Java 13
  • 58 = Java 14
  • 59 = Java 15
  • 60 = Java 16
  • 61 = Java 17
  • 62 = Java 18
  • 63 = Java 19
  • 64 = Java 20
  • 65 = Java 21
  • 66 = Java 22

3. 命令行方式

现在我们来讨论一下如何解决从命令行运行 Java 时出现的错误。

根据我们的情况,有两种方法可以解决这个错误:选择在低版本 Java 上重新编译代码,或者安装高版本 Java 运行项目。

最终的决定取决于我们的情况。如果我们需要使用已编译到较高版本的第三方库,最好的选择可能是使用较新的 Java 版本运行应用程序。如果我们要打包发布应用程序,最好编译到较旧的版本。

3.1. JAVA_HOME 环境变量

首先检测 JAVA_HOME 环境变量是否设置,以获知当前使用的 JDK 版本。

echo %JAVA_HOME%
C:\Apps\Java\jdk8-x64

如果我们已经下载了新的 JDK 版本, 请确保 JAVA_HOME 环境变量是否设置正确.

3.2. 运行在新的 JRE 上

回到我们的示例,让我们看看如何通过在更高版本的 Java 中运行来解决错误。假定我们的 Java 11 JRE 位于 C:\Apps\jdk-11.0.2

C:\Apps\jdk-11.0.2\bin\java com.baeldung.MajorMinorApp
Hello World!

3.3. 使用旧版本编译

如果我们要编写一个应用程序,并希望它能在某个 Java 版本下运行,我们就需要编译该版本的代码。

我们有三种方法:使用旧版 JDK 编译代码;使用 javac 命令的 -bootclasspath、-source 和 -target 选项(JDK 8 及更旧版本);或使用 -release 选项(JDK 9 及更新版本)。

让我们从使用老的 JDK 开始,就像我们使用较新的 JRE 运行代码一样:

C:\Apps\Java\jdk1.8.0_31\bin\javac com/baeldung/MajorMinorApp.java

可以只使用 -source 和 -target,但这样创建的类文件仍可能与旧版 Java 不兼容。

为确保兼容性,我们可以将 -bootclasspath 指向目标 JRE 的 rt.jar:

javac -bootclasspath "C:\Apps\Java\jdk1.8.0_31\jre\lib\rt.jar" \
  -source 1.8 -target 1.8 com/baeldung/MajorMinorApp.java

上述内容主要适用于 JDK 8 及更低版本。**在 JDK 9 中,-release 参数被添加进来,以取代 -source 和 -target 参数。-release 选项支持目标 6、7、8、9、10 和 11。

javac --release 8 com/baeldung/MajorMinorApp.java

现在,我们可以在 Java 8 或更高版本的 JRE 上运行我们的代码了。

4. Eclipse IDE 配置方法

前面我们已经学习了产生该错误的原因是Java版本问题导致,并学习了如何在命令行下解决该问题,在Eclipse中解决该问题很简单。

4.1. 修改 JRE

假设我们已经在 Eclipse 配置了不同版本的 Java,现在让我们更改项目的 JRE 版本。

进入 Project properties 选择 Java Build Path,然后 Libraries tab,选择 JRE 并点击 Edit 按钮。

ProjectPropertiesLib

选择 Alternate JRE 并我们选择安装的 Java 11:

ProjectEditJRE11

现在,我们的应用程序将在 Java 11 中运行。

4.2. 修改编译级别

现在,让我们看看如何将目标改为较低级别的 Java。

首先回到 Project properties, 选择 Java Compiler, 点击 Enable project specific settings:

BAEL 2308_ProjectPropertiesCompilerLevel

在这里,我们可以将项目设置为针对早期版本的 Java 进行编译,并自定义其他合规性设置:

BAEL 2308_ProjectPropertiesCompilerLevel_dropdown

5. IntelliJ IDEA 配置方法

前面我们已经学习了产生该错误的原因是Java版本问题导致,并学习了如何在命令行下解决该问题,在IDEA中解决该问题很简单。

5.1. 添加 JDK

在此之前,我们先看看如何添加其他版本的 JDK。进入设置 File -> Project Structure -> Platform Settings -> SDKs

BAEL 2308_IDEA_AddSDK1

点击中间一列的加号图标,从下拉菜单中选择 JDK,然后选择我们的 JDK 位置:

IDEA_AddSDK2_2

5.2. 修改 JRE

首先,我们来看看如何使用 IDEA 在较新的 JRE 上运行我们的项目。

进入设置 Run -> Edit Configurations… 修改 JRE 到 11:

IDEA_ChangeJRE

现在,当我们运行项目时,它将使用 Java 11 JRE 运行。

5.3. 修改编译级别

如果我们要将应用程序发布到较低版本的 JRE 上运行,就需要调整编译器级别,使其针对较旧版本的 Java。

进入设置 File -> Project Structure… -> Project Settings -> Project 修改 Project SDKProject language level:

IDEA_ChangeTargetLevel

现在我们可以构建项目,生成的类文件将在 Java 8 及更高版本上运行。

6. Maven 配置方法

当使用 Maven 构建和打包项目时,我们可以控制Java版本。

使用 Java 8 或更高版本时,我们要为编译器插件设置source和taget。

使用编译器插件属性来设置:

<properties>
    <maven.compiler.target>1.8</maven.compiler.target>
    <maven.compiler.source>1.8</maven.compiler.source>
</properties>

或者,我们也可以在编译器插件中设置:

<plugins>
    <plugin>    
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
            <source>1.8</source>
            <target>1.8</target>
        </configuration>
    </plugin>
</plugins>

Java 9 中添加了 -release 选项,我们也可以通过 Maven 进行配置。

<properties>
    <maven.compiler.release>8</maven.compiler.release>
</properties>

或者直接

<plugins>
    <plugin>    
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
            <release>8</release>
        </configuration>
    </plugin>
</plugins>

7. 总结

在本文中,我们了解了 java.lang.UnsupportedClassVersionError: Unsupported major.minor version 错误信息的原因,以及如何修复它。