1. 概要

このチュートリアルでは、Java9の新しいコマンドラインオプションについて学習します。 -リリース。 で実行されているJavaコンパイラ –リリースN オプションは、JavaバージョンNと互換性のあるクラスファイルを自動的に生成しますこのオプションが既存のコンパイラコマンドラインオプションとどのように関連するかについて説明します -ソース -目標。

2. —リリースオプションの必要性

release オプションの必要性を理解するために、コードをJava 8でコンパイルし、コンパイルされたクラスにJava7との互換性を持たせる必要があるシナリオを考えてみましょう。

これは、Java 9より前の— source および— target オプションを使用して実現できました。ここで、

  • -ソース:は、コンパイラが受け入れるJavaバージョンを指定します
  • -target:は、生成するクラスファイルのJavaバージョンを指定します

コンパイルされたプログラムが、プラットフォームの現在のバージョン(この場合はJava 8)でのみ使用可能なAPIを使用するとします。 その場合、コンパイルされたプログラムは、– source および– target オプションに渡された値に関係なく、Java7などの以前のバージョンでは実行できません。

さらに、Javaバージョン8以下で動作するには、– bootclasspath オプションを– source および– targetとともに追加する必要があります。

このクロスコンパイルの問題を合理化するために、Java 9は新しいオプション— releaseを導入してプロセスを簡素化しました。

3. -s ourceおよび-targetオプションとの関係

JDK定義によると、 –releaseNは次のように展開できます。

  • N<9の場合 -ソース N -目標 N -bootclasspath
  • N>=9の場合 -ソース N -目標 N -システム
これらの内部オプションに関する詳細は次のとおりです。
  • -bootclasspath:ブートクラスファイルを検索するためのディレクトリ、JARアーカイブ、およびZIPアーカイブのセミコロン区切りのリスト
  • system :Java9以降のバージョンのシステムモジュールの場所を上書きします
また、文書化されたAPIは $ JDK_ROOT / lib / ct.sym にあります。これは、Javaバージョンに従って削除されたクラスファイルを含むZIPファイルです。

JavaバージョンN<9の場合、これらのAPIには、にあるjarから取得されたブートストラップクラスが含まれます。 jre / lib / rt.jar およびその他の関連するjarファイル。

JavaバージョンN>=9の場合、これらのAPIには、 jdkpath / jmods/ディレクトリにあるJavaモジュールから取得されたブートストラップクラスが含まれます。

4. コマンドラインでの使用

まず、サンプルクラスを作成し、Java9で追加されたByteBufferのオーバーライドされたflipメソッドを使用してみましょう。

import java.nio.ByteBuffer;

public class TestForRelease {

    public static void main(String[] args) {
        ByteBuffer bb = ByteBuffer.allocate(16);
        bb.flip();
        System.out.println("Baeldung: --release option test is successful");
    }
}

4.1. 既存の-sourceおよび-targetオプションを使用

-sourceおよび-targetオプション値を8として使用して、Java9のコードをコンパイルしてみましょう。

/jdk9path/bin/javac TestForRelease.java -source 8 -target 8 

この結果は成功しますが、警告が表示されます。

warning: [options] bootstrap class path not set in conjunction with -source 8

1 warning

それでは、Java8でコードを実行してみましょう。

/jdk8path/bin/java TestForRelease

これが失敗することがわかります。

Exception in thread "main" java.lang.NoSuchMethodError: java.nio.ByteBuffer.flip()Ljava/nio/ByteBuffer;
at com.corejava.TestForRelease.main(TestForRelease.java:9)

ご覧のとおり、これは、-releaseおよび-targetオプションで指定された値8で期待したものではありません。 したがって、コンパイラはそれを考慮する必要がありますが、そうではありません。

これをもっと詳しく理解しましょう。

Java 9より前のリリースでは、Bufferクラスにflipメソッドが含まれていました。

public Buffer flip() {
    ...
 }

Java 9では、 ByteBuffer、 Bufferを拡張するフリップメソッドをオーバーライドします。

@Override
public ByteBuffer flip() {
    ...
}

この新しいメソッドをJava9でコンパイルしてJava8で実行すると、両方のメソッドの戻りタイプが異なり、記述子を使用したメソッドのルックアップが実行時に失敗するため、エラーが発生します。

Exception in thread "main" java.lang.NoSuchMethodError: java.nio.ByteBuffer.flip()Ljava/nio/ByteBuffer;
at com.corejava.TestForRelease.main(TestForRelease.java:9)

 

コンパイル中に、以前は無視した警告が表示されました。 これは、Javaコンパイラがデフォルトで最新のAPIでコンパイルされるためです。 つまり、 –source と–targetを8に指定したにもかかわらず、コンパイラーはJava 9クラスを使用したため、プログラムはJava8で実行できませんでした。

したがって、正しいバージョンを選択するには、– bootclasspathという別のコマンドラインオプションをJavaコンパイラに渡す必要があります。

それでは、同じコードを– bootclasspath option で再コンパイルしましょう。

/jdk9path/bin/javac TestForRelease.java -source 8 -target 8 -Xbootclasspath ${jdk8path}/jre/lib/rt.jar

繰り返しになりますが、これの結果は成功しており、今回は警告はありません。

次に、Java 8でコードを実行すると、これが成功していることがわかります。

/jdk8path/bin/java TestForRelease 
Baeldung: --release option test is successful

現在、クロスコンパイルは機能していますが、3つのコマンドラインオプションを提供する必要がありました。

4.2. –releaseオプションあり

それでは、 –releaseオプションを使用して同じコードをコンパイルしましょう。

/jdk9path/bin/javac TestForRelease.java —-release 8

繰り返しになりますが、今回は警告なしでコンパイルが成功しました。

最後に、Java 8でコードを実行すると、成功していることがわかります。

/jdk8path/bin/java TestForRelease
Baeldung: --release option test is successful

javacが内部で-source、-target、および–bootclasspathの正しい値を設定するため、—releaseオプションを使用すると簡単であることがわかります。

5. Mavenコンパイラプラグインでの使用

通常、コマンドライン javac ツールではなく、MavenやGradleなどのビルドツールを使用します。 したがって、このセクションでは、Mavenコンパイラプラグインで –releaseオプションを適用する方法を説明します。

まず、既存の-sourceおよび-targetオプションをどのように使用するかを見てみましょう。

<plugins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.1</version>
        <configuration>
            <source>1.8</source>
            <target>1.8</target>
        </configuration>
    </plugin>
 </plugins>

–releaseオプションの使用方法は次のとおりです。

<plugins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.1</version>
        <configuration>
            <release>1.8</release>
        </configuration>
    </plugin>
 </plugins>

動作は前に説明したものと同じですが、これらの値をJavaコンパイラに渡す方法は異なります。

6. 結論

この記事では、 –release オプションと、既存の-sourceおよび-targetオプションとの関係について学習しました。 次に、コマンドラインとMavenコンパイラプラグインでこのオプションを使用する方法を確認しました。

最後に、新しい— release オプションでは、クロスコンパイルに必要な入力オプションが少ないことがわかりました。 このため、 -target、-source、 -bootclasspath optionsの代わりに可能な限り使用することをお勧めします。