テストがあります:
public class ResourceTest {
@Test
public void test() throws ClassNotFoundException {
Class.forName("javax.annotation.Resource");
}
}
にアクセスしようとしますjavax.annotation.Resource
。Java 8ではうまくいきましたが、Java 9(Oracle JDK 9を使用しています)では失敗しますClassNotFoundException
。ここで説明されているようにSpring: @Resource インジェクションが JDK9 で動作しなくなったは、javax.annotation.Resource
JDK から Java 9 ではデフォルトで利用できません。
モジュール記述子を使用してアクセスしようとしています:
module test {
requires java.xml.ws.annotation;
requires junit;
}
java.xml.ws.annotation
ここでは、モジュール ( を含む)へのアクセスを具体的に要求していますjavax.annotation.Resource
。しかし、テストは依然として失敗します。
その句を削除しrequires
、 を含む依存関係 (ライブラリとして) を追加するとjavax.annotations.Resource
、次のように動作します。
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.1</version>
</dependency>
両方を追加すると (およびの Maven 依存関係pom.xml
) requires java.xml.ws.annotation
、IDEA でのコンパイルが失敗し、次のメッセージが表示されます。
the unnamed module reads package javax.annotation from both java.xml.ws.annotation and java.annotation
しかし、Maven ビルドは依然として成功します。
コマンドラインでモジュールを追加するとjava.xml.ws.annotation
、Mavenの依存関係なしで動作します。と requires
句):
mvn clean test -DargLine="--add-modules java.xml.ws.annotation"
モジュールの説明に何か問題があるのでしょうか?javax.annotation.Resource
コマンドラインスイッチを使用せずに JDK 提供にアクセスするにはどうすればよいですか?
テストプロジェクトは以下から入手可能です。https://github.com/rpuch/test-resource-jdk9
ベストアンサー1
ここで混乱を解消します。質問で述べられている作業方法は選択肢であり、すでに見たように組み合わせるべきではありません。
名前のないモジュールは、java.xml.ws.annotationとjava.annotationの両方からパッケージjavax.annotationを読み取ります。
したがって、動作方法は次のいずれかになります。
コンパイラ引数を使用してモジュールを追加できます
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<release>9</release>
<compilerArgs>
<arg>--add-modules</arg>
<arg>java.xml.ws.annotation</arg>
</compilerArgs>
</configuration>
</plugin>
または
javax.xml.ws.annotation
存在を活用するアップグレード可能なモジュール依存関係を活用できるとき
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.1</version>
</dependency>
理想的には、前者は単に代替手段であるため、これを使用するのが好ましい選択肢です。@非推奨モジュールがマークされていますforRemoval
。
したがって、必要な句だけではモジュールにアクセスするには不十分です...これは、すべての JDK 提供モジュール (java.base を除く) に当てはまりますか、それとも非推奨のモジュールにのみ当てはまりますか?
いいえ、これはrequires
宣言の一部にすぎません。[考えてみてください。JDK 9 より前のバージョンでは、import some.foo.bar;
ライブラリ (クラスパス) として追加されていないステートメントをクラスで使用した場合、それは機能したでしょうか?]。必須としてマークされたモジュールは、アクセスするためにモジュールパス上に存在する必要があります。
アップデート- 最初のオプションは、JDK/11以降ではサポートされなくなり、JEPはJava EEおよびCORBAモジュールを削除する対象となります。