关于jvm:如何修复java.lang.unsupportedClassVersionError:不支持的major.minor版本

How to fix java.lang.UnsupportedClassVersionError: Unsupported major.minor version

我正在尝试使用记事本++作为我的一个综合工具编辑、运行、编译等。

我安装了JRE,并将路径变量设置到.../bin目录。

当我在记事本+中运行"Hello World"时,会收到以下消息:

1
2
3
4
5
java.lang.UnsupportedClassVersionError: test_hello_world :
 Unsupported major.minor version 51.0
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClassCond(Unknown Source)
       .........................................

我认为这里的问题是关于版本;一些版本的Java可能是旧的或太新的。

  • 我该怎么修?
  • 我应该安装JDK,并将路径变量设置为JDK而不是JRE吗?
  • jre或jdk中的PATH变量有什么区别?

  • 显示的版本号描述类文件兼容的JRE版本。

    报告的主要数字是:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Java SE 13 = 57,
    Java SE 12 = 56,
    Java SE 11 = 55,
    Java SE 10 = 54,
    Java SE 9 = 53,
    Java SE 8 = 52,
    Java SE 7 = 51,
    Java SE 6.0 = 50,
    Java SE 5.0 = 49,
    JDK 1.4 = 48,
    JDK 1.3 = 47,
    JDK 1.2 = 46,
    JDK 1.1 = 45

    (来源:维基百科)

    要解决实际问题,您应该尝试用Java JRE的新版本运行Java代码,或者指定Java编译器的目标参数,以指导编译器创建与早期Java版本兼容的代码。

    例如,为了生成与Java 1.4兼容的类文件,请使用以下命令行:

    1
    javac -target 1.4 HelloWorld.java

    使用Java编译器的更新版本,您可能会获得关于未设置引导类路径的警告。有关此错误的详细信息,请参阅日志new javac warning,该警告用于设置不带bootclasspath的旧源。


    java.lang.UnsupportedClassVersionError的发生是因为编译时JDK较高,运行时JDK较低。


    在Eclipse中,我刚进入菜单命令窗口>首选项> java>编译器,然后将"编译器遵从级别"设置为1.6。


    别担心,我已经解决了。

    这实际上很简单——您需要用相同的版本安装两个JRE/JDK。

    JRE 6>JDK 6

    JRE 7>JDK 7

    等等。


    这个错误意味着你试图加载一个Java"类"文件,该文件是用一个新版本的Java编译的,而不是你已经安装的。

    例如,您的.class文件可能是为JDK7编译的,您正试图用JDK6运行它。

    因此,解决方案是:

    • 升级Java运行时或
    • 如果你有源代码,使用本地Java编译器(如果你有一个),就重新编译这个类。

      javac文件名.java

    对于开发人员来说,如果另一个开发人员在.class文件中进行检查,那么他们可能会出现一个比你拥有的Java版本更高的版本!


    您试图用不支持编译代码的版本的Java版本运行程序。所以基本上你必须用更高的版本编译你的代码,并尝试用更低的版本运行它。

    当你得到

    1
    Unsupported major.minor version 51.0

    版本51对应于J2SE 7,您可能最有可能在Java 7中编译代码,并尝试使用较低版本运行代码。检查java -version显示的内容。它应该是Java 7版本。如果没有,请在路径/java_home中进行适当的更改。或者您可以使用试图运行代码的相同版本进行编译。如果配置混乱,可以始终给出绝对路径/home/user/jdk1.7.0_11/bin/javac/home/user/jdk1.7.0_11/bin/java


    我在Mac上也有类似的情况,下面的过程对我很有效:

    在终端中,键入

    1
    vi ~/.profile

    然后将此行添加到文件中,并保存

    1
    export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk<version>.jdk/Contents/Home

    其中version是您计算机上的版本,如1.7.0_25

    退出编辑器,然后键入以下命令使其生效

    1
    source ~/.profile

    然后键入Java版本检查结果

    1
    java -version

    什么是.profile文件?

    .profile file is a hidden file. It is an optional file which tells the system which commands to run when the user whose profile file it is logs in. For example, if my username is bruno and there is a .profile file in /Users/bruno/, all of its contents will be executed during the log-in procedure.

    资料来源:http://computers.tutspus.com/tutorials/speed-up-your-terminal-workflow-with-command-aliases-and-profile--mac-30515


    在Eclipse的菜单窗口->首选项> java>编译器检查也"配置项目特定的设置"。

    如果您仍然具有相同Java版本的错误:请手动删除项目的生成文件夹。然后重新启动Eclipse。


    您可以在Java 7中编译一些JAR库,而Java 6只作为Java运行时。有些新图书馆可能会出现这种情况。


    最常见的问题是如果您安装了多个EDCOX1的12变量,则应该指向正确的Java开发工具包库。

    若要查找SDK Java文件夹所在的位置,请运行以下命令:

    1
    jrunscript -e 'java.lang.System.out.println(java.lang.System.getProperty("java.home"));'

    Debian/Ubuntu

    要检查您安装了哪种Java(OpenJDK),请检查:

    1
    dpkg -l"openjdk*" | grep ^i

    或:

    1
    update-java-alternatives -l

    要更改它,请使用:

    1
    update-alternatives --config java

    如果需要,前缀为sudo

    选择替代的Java版本。

    或检查可用于安装的:

    1
    apt-cache search ^openjdk

    如果需要,前缀为sudo

    然后可以安装,例如:

    1
    apt-get install openjdk-7-jre

    如果需要,前缀为sudo

    Fedora、Oracle Linux、Red Hat

    通过以下方式安装/升级适当的软件包:

    1
    yum install java-1.7.0-openjdk java-1.7.0-openjdk-devel

    The java-1.7.0-openjdk package contains just the Java Runtime Environment. If you want to develop Java programs then install the java-1.7.0-openjdk-devel package.

    BSD

    FreeBSD端口集合中有一个名为OpenJDK7的OpenJDK 7包,可能需要重新配置。

    请参见:openjdk wiki页面。

    窗户

    只需从Oracle站点或安装中安装适当的JavaSE开发工具包库即可

    詹金斯

    如果您遇到Jenkins的问题,请参阅:

    • Jenkins-30561-无法使用ssh启动代理

    然而,选择具有EDCOX1(16)的Java(NeXER)的正确版本应该是有效的。


    当我使用Ant脚本构建我的应用程序时,我也遇到了同样的问题。

    我将Eclipse用于应用程序开发,并在项目的构建属性中更改了编译器版本。但那对我不起作用。然后我发现我可以在Ant脚本中提供编译器版本。

    在编译Java文件的部分,我修改了Ant脚本。

    1
    2
    3
    4
    5
    6
    <target name="build-java" depends="prepare-build">
        <echo message="Compiling java files"/>
        <javac ....
               target="1.5"...
        </javac>
    </target>

    这对我解决不支持的主要次要问题很有帮助。


    我在1.7中编写的一个项目中遇到了同样的问题,并尝试在1.6中执行。

    我在Eclipse中的解决方案:

    • 右击项目属性-> Java构建路径->库

    • 选择您的JRE系统库并单击右侧的"编辑",然后选择目标JRE。

    • 现在转到左边的Java编译器,并将编译器遵从性级别更改为目标。

    这对我很有用。


    当我安装JDK1.7时,问题得到了解决。


    正如其他人回答的那样,Java程序正在运行的Java版本比它编译的版本要长。为了向后兼容,它需要"交叉编译"。换句话说,源代码和目标Java版本之间存在不匹配。

    更改Eclipse菜单中的选项并不能回答最初的海报,海报上说他/她没有使用Eclipse。在openjdk javac版本1.7上,如果使用参数-source-target并在编译时提供目标版本(即旧版本)的rt.jar文件,则可以为1.6进行交叉编译。如果您实际安装了1.6 JRE,那么您可以指向它的安装(例如,Ubuntu上的/usr/lib/jvm/java-6-openjdk-i386/jre/lib/rt.jar,sunos上的/usr/jdk/jdk1.6.0_60/jre/lib/rt.jar)。抱歉,我不知道它在Windows系统上的位置)。像这样:

    1
    javac -source 1.6 -target 1.6 -bootclasspath /usr/lib/jvm/java-6-openjdk-i386/jre/lib/rt.jar HelloWorld.java

    看起来你可以从互联网上下载rt.jar,然后指向它。但这并不太优雅:

    1
    javac -source 1.6 -target 1.6 -bootclasspath ./rt.jar HelloWorld.java


    • 如果使用Maven,则设置Java编译级别。打开命令行并为编译级别编写java -version

      Enter image description here

    • 如果使用因特利思思想,选择Project"文件"、"设置"、"生成执行部署"、"编译器"、"Java编译器"。然后将字节代码更改为1.7,如图所示:

      Enter image description here


    如果在使用Maven时遇到这个问题,可以使用插件Maven编译器编译代码。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    maven-compiler-plugin</artifactId>
                    <version>3.1</version>
                    <configuration>
                        <source>1.6</source>
                        <target>1.6</target>
                    </configuration>
                </plugin>
           .....

    更新:如果使用JDK 8,则将sourcetarget设置为1.8


    基于此…

    1
    2
    3
    4
    5
    6
    7
    8
    J2SE 8 = 52
    J2SE 7 = 51
    J2SE 6.0 = 50
    J2SE 5.0 = 49
    JDK 1.4 = 48
    JDK 1.3 = 47
    JDK 1.2 = 46
    JDK 1.1 = 45

    在Eclipse中,右键单击包资源管理器中的项目:

    生成路径->配置生成路径

    下:

    Java构建路径->库->添加库-> JRE系统库>安装的JRES>搜索。

    通过在搜索完成后可用的列表中选择库来添加所需的JRE。


    我在从Eclipse运行Ant时收到了相同的错误消息,但是这里提到的其他解决方案并没有解决我的问题。有趣的是,从Windows命令行运行Ant运行得很好,所以它必须是Eclipse中的一个配置问题。

    事实证明,在Eclipse下,您可以指定Ant应该运行的环境,并且将其设置为JRE而不是JDK。

    • 转到:运行->外部工具->外部工具配置…
    • 为您的项目选择antbuild.xml(如果您有多个项目)
    • 激活"JRE"选项卡
    • 这里选择了"单独的JRE:JRE6"。当我将它从1.6或1.7系列更改为JDK时,错误就消失了。

    How do I fix it?

    这个错误意味着用于执行类代码的JRE不能识别所使用的Java版本。通常是因为生成了类文件(即编译它)的Java版本更新了。

    要修复它,您可以

    a)用Java编译器编译Java源的相同或更旧版本,用于运行它。即安装适当的JDK。

    b)用Java编译器的新版本编译Java源,但以兼容模式编译。即使用-target参数。

    c)在JRE中运行编译的类,该JRE的版本与用于编译类的JDK的版本相同或更新。

    您可以检查当前使用的版本用于编译器的javac -version,用于运行时的java -version

    Should I install the JDK, and setup my PATH variable to the JDK
    instead of JRE?

    对于编译,当然要安装和配置您想要的特定JDK。

    对于运行时,您可以使用JDK或独立JRE附带的版本,但是无论如何,请确保您安装了正确的版本,并且您已经配置了路径,这样就不会有任何意外。

    What is the difference between the PATH variable in JRE or JDK?

    path环境变量告诉命令shell在哪里查找您键入的命令。当您键入java时,命令shell解释器将从左到右查看PATH变量中指定的所有位置,以找到要运行的适当java运行时可执行文件。如果您安装了多个Java版本,即在路径变量中指定的多个位置上有EDOCX1 3可执行,那么从左到右遇到的第一个将是执行的一个。

    编译器命令是javac,只随JDK一起提供。运行时命令是java,与jdk一起提供,并在jre中。

    可能有一个版本(51=Java 7)安装了EDOCX1 7,并且您也安装了EDOCX1 3版本的相同版本,但是EDCOX1的另一个以前版本(3)在路径中出现得更早,因此被调用而不是您期望的那个版本。


    您已经使用了更高版本的JDK来编译并尝试从较低版本的JDK/JRE运行。

    要检查此项,请参阅版本信息:

    1
    2
    3
    javac -version

    java -version

    它们会有所不同,javac的版本号也会更高。

    为了绕过这个问题,使用Java从JDK版本运行,或者如果您有一个更新的JRe/JDK,那么它也可以工作。

    which javac将告诉您位置,例如,/usr/bin/javac。直接使用/usr/bin/java 运行。

    或者可以将环境变量设置为永久解决方案。


    当我恢复到Java 6并尝试运行以前用Java 7编译的类时,出现了这个问题。对我起作用的是首选项> java>编译器> >设置符合级别为1.6,最重要的是"配置项目设置"。


    您的Java文件是用不同版本(更高版本)编译的,而不是试图运行的版本(下运行时版本)。

    基本的理解是,使用较低版本编译的类将在较新的较高版本中运行。但是,相反的情况(使用更高的编译器版本编译,并尝试使用更低的运行时版本运行)有时是不可能的。

    因此,在尝试执行程序时会显示此错误。不支持的major.minor版本x.x

    Q: I have created an application in Java 7, but when my users try to
    run it they get an Unsupported major.minor version 51.0 error. What
    does this mean and what can I do about it?

    A: If you compile an application using javac in Java 7, the resulting classfiles will have the 51.0 version number. Versions of
    Java prior to 7 do not recognize this number, so your users will have
    to upgrade to Java 7 prior to running your application. If you are not
    using any Java 7 APIs you can try to compile your application using
    javac -target 1.6 to create a 1.6-compatible classfile. If your
    application is deployed using webstart you can specify the minimum
    version required. For more information, see the docs on Java Web Start
    and JNLP here. This issue will go away once we trigger autoupdate to
    Java 7 for end-users currently having Java 6 on their desktops. The
    timeline for this is not yet determined, we want to give developers
    time to work out any issues between their code and JDK 7 first.

    (来源:oracle.com。)


    今天,这个错误消息出现在Ubuntu 12.04.2 LTS(精确穿山甲)上的Tomcat 7中:

    /var/log/tomcat7/localhost.2014-04-08.log:
    Apr 8, 2014 9:00:55 AM org.apache.catalina.core.StandardContext filterStart
    SEVERE: Exception starting filter struts2
    java.lang.UnsupportedClassVersionError: controller/ReqAccept : Unsupported major.minor version 51.0 (unable to load class controller.ReqAccept)

    Struts应用程序是用Java 7编译的。

    事实证明,有人使用"服务Tomcat[停止/启动]"重新启动Tomcat 7,

    $ ps -ef | grep java
    tomcat7 31783 1 32 20:13 ? 00:00:03 /usr/lib/jvm/default-java/bin/java...
    $ /usr/lib/jvm/default-java/bin/java -version
    java version"1.6.0_27"

    这会导致"不支持的major.minor版本51.0"错误。

    当我们使用"/etc/init.d/tomcat7[停止/启动]"重新启动tomcat7时,问题解决了。

    $ ps -ef | grep java
    tomcat7 31886 1 80 20:24 ? 00:00:10 /usr/local/java/jdk1.7.0_15/bin/java
    $ /usr/local/java/jdk1.7.0_15/bin/java -version
    java version"1.7.0_15"


    我解决了它。我跑了:

    1
    JAVA_HOME=/usr/lib/jvm/java-7-openjdk-i386

    错误是误导性的,Unsupported major.minor version 51.0。这给人的印象是不支持版本51(Java 7)。我们应该使用Java 6。

    错误应该是:

    The current Java version, 50, is unsupported. Use Java version 7 (51:0 and greater) instead.`


    哦,Mac OS X我可以通过设置java_home变量来解决这个问题:

    1
    export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.0_75.jdk/Contents/Home

    首先,让我们做一些基本的事情…

    JRE是NETBeaSe/Eclipse/Stand中的一个组件,它将为您提供库、JVM、Java插件和Java Web启动。请注意,它不提供编译器或调试器。

    JDK是JRE以及编译器和调试器的超集。

    因此,当您将默认库作为JRE而不是JDK时,您将有一个很好的时间导入东西,但它不会编译。

    相反,将您的路径设置为jdk(我使用netbeans,并在netbeans/etc/netbeans.conf中使用netbeans.conf设置它们,然后更改路径)。


    在我的例子中,问题出在服务器运行时配置中:

    Server Runtime Environment

    检查JRE是否是您需要的版本:

    enter image description here

    该项目在1.7版,服务器JRE设置为1.6,在更改为适当的Java版本后,它就启动了。


    我遇到了这样的问题:为了运行我的单元测试,我必须从命令行在我的项目上运行maven编译;如果我对测试类进行了更改,并让Eclipse自动重新编译它,那么我得到了"unsupported major.minor version 51.0"错误。

    我确实安装了JDK6和JDK7,但是我的所有JRE设置都指向1.6,无论是在POM中还是在Eclipse的项目属性页中。没有多少Maven更新项目和/或刷新解决了这个问题。

    最后,我试着关闭这个项目,重新打开它,这似乎解决了它!高温高压


    您已经用JDK 7编译了Java类,并且尝试在JDK 6上运行同一个类。


    • 安装JDK 7.0.55,并为JDK 7.0.55设置Eclipse的Java。
    • 通过在构建路径JDK 7.0.55上配置,使用JDK 7.0.55构建项目。
    • 将Java7.0.55中的编译器设置为Eclipse,菜单窗口->首选项> Java>编译器-选择1.7。

    问题的答案是:

    线程"main"java.lang.unsupportedClassVersionError:edu/stevens/cs549/dhts/main/localcontext:unsupported major.minor version 52.0中出现异常

    我也有同样的问题。对于那些在AWS EC2实例中遇到这种问题,并且不知何故被重定向到这个问题的人来说。我正在回答这些问题,并想分享我是如何做到的。我遇到了麻烦,因为Amazon EC2实例运行Java版本1.7,也许我的项目与它不兼容,因为我使用Maven,它对Java 1.8进行了预配置。所以我安装了新版本的Java:

    sudo yum -y install java-1.8.0

    然后重要的步骤是删除旧版本:

    1
    sudo yum remove java-1.7.0-openjdk

    记住在安装新版本后删除它,否则它将继续使用相同的旧版本,我希望它能解决您的问题,在我的情况下就是这样。


    在安装了自制的Mac OS X上解决此问题的另一种方法是:

    1
    brew install Caskroom/cask/java

    由于Java 9 EDCOX1,1,ED替换为EDCOX1,2。

    直到Java 11,EDCOX1的2个可用数字是EDCOX1,4,EDCOX1,5,EDCOX1,6,EDOCX1,7,EDOCX1,8,EDOCX1 9。你可以猜测未来的版本是1213,然后继续。

    为了编译旧的目标JVM,使用javac --release 7 Tmp.java/,这将生成.class文件,该文件可以在jvm>=7上运行,

    然后您可以通过以下方式检查目标版本:

    javap -v Tmp | grep version

    在输出中,major version标识目标JVM版本。

    • 55>Java 11
    • 54>Java 10
    • 53>Java 9
    • 52>Java 8
    • 51>Java 7
    • 50>Java 6

    未来版本将删除更多旧版本:

    • 对于Java 11,不支持主要版本<=49(Java版本<=5)。
    • 至于Java 12和13,不支持主要版本<=50(Java版本<=6)。

    您可以通过以下命令了解当前javac支持哪些目标版本:javac -help | grep releases


    我也面临同样的问题,我在Linux中修复了它。

    检查你的$JAVA_HOME

    需要JDK 1.8来编译/构建APK

    安装Java JDK 1.8并更改EDCOX1 OR 5

    编辑~/.bashrc并将JDK 1.8路径添加为JAVA_HOME

    export JAVA_HOME=/usr/lib/jvm/java-8-oracle/jre/

    source ~/.bashrc

    关闭当前终端窗口/选项卡,运行$JAVA_HOME检查路径。


    对我来说,我在com/sun/javadoc/Doclet课上遇到了这个错误。经过一番挖掘,我发现我意外地将EDCOX1 2从Java 8复制到我的Java 7文件夹中。

    找到Java 7的EDCOX1 2,并把它放回文件夹中修复了我的问题。所以要尝试一下。


    我什么都试过了。重新安装Tomcat是最终成功的。这是我重新安装前检查过的。

    确保你的环境变量是这样的。

    1
    2
    3
    4
    $ echo $JAVA_HOME
    C:\Program Files\Java\jdk1.7.0_51\
    $ echo $JRE_HOME
    C:\Program Files\Java\jdk1.7.0_51\jre\bin

    确保Eclipse使用的JRE与设置java_home的JRE相同(如果未设置java_home,则会查看jre_home)。Window > Prefrences > Java > Installed JREs(勾选为默认)

    如果您对您的任何Tomcat文件进行了任何更改,特别是Calalial.BAT或Stututu.BAT,那么您可能会告诉Tomcat查看与Java JavaHead EDOCX1 12所描述的版本不同的Java版本。


    确保您检查Java的环境变量版本,它可能只是EDOCX1 16版(JDK PATH)和EDCOX1 OR 17(JRE路径)版本之间的差异,这导致了问题的发生。


    如果您使用的是Ant,可以在build.xml文件中为编译器指定"目标",如下所示:

    1
    2
    3
    4
    5
    6
     <target name="compile" depends="init">
        <javac executable="${JAVA_HOME}\bin\javac" srcdir="${src.dir}" target="1.6" destdir="${classes.dir}" debug="true"
            deprecation="true" classpathref="compile.classpath" encoding="utf8">
            <include name="**/*.java" />
        </javac>
    </target>

  • 单击项目中的"属性"。
  • 转到Java构建路径。
  • 单击添加库。
  • 单击JRE系统库上的下一步。如果默认情况下未选择,请选择所需的选项。
  • 单击"完成"。
  • 你完了!


    我使用的是OSX V1011.5(EL CabpAn),我尝试设置JavaHOHE并强制通过Maven创建"正确"的Java版本。没什么帮助。

    当应用程序仍在运行时,OS X帐户注销时出现问题。再次登录后,OS X打开旧的终端会话,并显示灰色历史记录。我使用相同的终端会话来构建项目,但由于不支持的类版本错误而失败。

    清理Maven项目毫无帮助。

    为了解决这个问题,我只需要关闭自动打开的终端窗口并使用一个新的。


    我也遇到了同样的问题,我在Mac上通过这个解决方案解决了这个问题。我希望它能帮助别人。这是因为系统不知道JDK的新版本,它仍然指向旧的JDK。


    我通过检查部署程序集中是否部署了Maven依赖项来解决这个问题。在我的情况下,他们不是。

    添加它修复了问题。


    将此添加到pom.xml文件中:

    1
    2
    3
    4
    5
    6
    <project ....>
        <properties>
            <maven.compiler.source>1.7</maven.compiler.source>
            <maven.compiler.target>1.7</maven.compiler.target>
        </properties>
    </project>

    其中1.7是您打算使用的Java版本。这将覆盖maven编译器设置,因此从这里进行调试很好。


    对于Grails项目,我在SpringSourceTool(STS)IDE中也遇到了同样的问题。我检查了安装的Java版本,项目Java版本为1.7。后来我发现在GGTS.IN文件中,Java版本被设置为1.6:

    解决方案:

    -dosgi.requiredjavaversion=1.6改为-Dosgi.RequiredJavaersion=1.7在-vmargs前面的两行下面添加-虚拟机jdk1.7.0_21/jre/lib/amd64/server/libjvm.so

    问题解决了。快乐编码。


    正如你所知道的,对于JDK(Java开发工具包)bin目录,环境变量JavaJOHE总是很好的做法。

    看看上面的问题,JRE运行时环境似乎在寻找一个在JDK的超集库中不兼容的类。我建议直接从Oracle下载源下载完整的JDK和JRE或JBoss包(如果需要),以避免出现任何此类问题。


    我也有同样的情况,但是上面的任何一个提示都没有帮助:)在我们的环境中,我们让Tomcat在Windows上作为服务运行。我们安装了Java 1.7,并在这个版本上建立了JavaJHOLD。当然,源代码是在Java 1.7上构建的。不过,Tomcat说它使用了以前版本的JVM。在深入分析之后,安装在Windows上的Tomcat服务仍然保持JavaJHOLD指向Java 1.6的旧值。安装新的Tomcat服务后,一切都解决了。因此,结论是:当将Java版本和Tomcat作为服务运行时,必须重新安装Tomcat服务。


    如果在构建路径中添加了第二个项目,请确保它与第一个项目具有相同的编译器版本:属性> > Java编译器>编译器遵从级别