web-dev-qa-db-ja.com

Java JDK、コンパイラのバージョンはJavaランタイムと互換性がありません

javacで呼び出される単純なHello Worldをコンパイルしようとしましたが、「Java Hello」コマンドを使用すると、JVMはバイトコードを読み取れないようです。

「Java Hello」の出力:

Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" Java.lang.UnsupportedClassVersionError: Hello has been compiled by a more recent version of the Java Runtime (class file version 57.0), this version of the Java Runtime only recognizes class file versions up to 52.0

        at Java.lang.ClassLoader.defineClass1(Native Method)
        at Java.lang.ClassLoader.defineClass(Unknown Source)
        at Java.security.SecureClassLoader.defineClass(Unknown Source)
        at Java.net.URLClassLoader.defineClass(Unknown Source)
        at Java.net.URLClassLoader.access$100(Unknown Source)
        at Java.net.URLClassLoader$1.run(Unknown Source)
        at Java.net.URLClassLoader$1.run(Unknown Source)
        at Java.security.AccessController.doPrivileged(Native Method)
        at Java.net.URLClassLoader.findClass(Unknown Source)
        at Java.lang.ClassLoader.loadClass(Unknown Source)
        at Sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at Java.lang.ClassLoader.loadClass(Unknown Source)
        at Sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)
2
Luigi Guerrera

エラーメッセージは(うまくいけば)かなり明確です:

Java.lang.UnsupportedClassVersionError:

こんにちはJavaランタイムの最新バージョン(クラスファイルバージョン57.0)によってコンパイルされました。このバージョンのJavaランタイムは、52.0までのクラスファイルバージョンのみを認識します

使用したコンパイラーは、Javaランタイム(JRE)が理解できないJavaバイトコードを生成しました。これは、JREが古すぎる(特に、コンパイルに使用したJDKよりも古い)ためです。

Javaコードをコンパイルすると、コンパイラはJavaバイトコードを生成します。 Javaバイトコードにはさまざまなバージョンがあり(新しいJavaリリースごとに、通常、新しいバージョンのバイトコードが導入されます)、バージョンが新しすぎると、古いJREはバイトコードを実行できません。

これを解決するには2つの方法があります。

1)-targetオプションを使用する

原則として、古いJRE用にコンパイルするようコンパイラーに指示することでこれを解決できます-これは、javac-targetオプションを使用して行われます(たとえば、 Java 9 )。

例えば、

javac -target 1.8 HelloWorld.Java

Java 1.8(別名Java 8)からJREのバイトコードをコンパイルします。エラーメッセージで言及されているバイトコードバージョン52がJava 8に対応しているため、これにより発生するエラーが解決されます(バイトコードバージョンをJavaリリースにマッピングするテーブルについては、ウィキペディアのページ Javaクラスファイル )。

このアプローチで発生するエラーは解決しますが、コンパイルするJava APIに関連する他の問題が発生する可能性があることに注意してください-javacオプション-bootclasspathを使用する必要があります、またはJava 9以降を使用している場合は-release

2)一致するJRE/JDKを使用する

ソリューション1)が複雑に聞こえる場合、それは:-)が原因です。

特に学習段階にある場合の実用的な解決策は、仮想マシン/ JREとコンパイラの一致するバージョンを単純に使用することです。最も簡単な方法は、 JDKダウンロードでインストールされたJREを使用するには(つまり、同じダウンロードからのJavajavacを使用)。

これは実際には、JDKをダウンロードしてインストールした後、デフォルトで何が起こるかです。そのため、エラーはおそらく2番目(3番目)のJREがどこかにインストールされていることを意味します。

実用的な場合は、使用する1つのJDKを除いて、すべてのJREとJDKをアンインストールします。並行して複数のJREが必要な場合は、構成(PATH変数、IDE configなど)がすべて同じJDKを指していることを確認してください。それはこれらの問題を回避します。

一部のIDE(Eclipseなど)にはコンパイラが組み込まれていることに注意してください。インストールしたJDKのバージョンと一致させるために個別に設定するか、IDEを推奨されるJDKバージョンと使用することが理想的です。 IDE。

1
sleske