Java 9が間近に迫っています。私のプロジェクトの一部をJava 9.に移植するのは良い学習課題だと思いました。 rxjava および rxjavafx の依存関係があります
dependencies {
compile 'io.reactivex:rxjava:1.2.6'
compile 'io.reactivex:rxjavafx:1.0.0'
...
}
このプロジェクトを名前付きモジュールとして作成したいと思います。これを行うには、module-info.Java
ファイルを作成し、rxjava
およびrxjavafx
の要件をここで指定する必要があります。ただし、これらのライブラリにはまだモジュール情報がありません。
これを回避するために、私はそれを読みました 自動モジュールを作成する必要があります 。理解したことから、rxjava
およびrxjavafx
jarの名前を単純な名前に変更し、--module-path
パラメーターにjarをリストする必要があります。次に、module-info.Java
にrequires
ディレクティブをjar名とともに追加します。
module com.foo.bar {
requires rxjavafx;
requires rxjava;
}
私はjar名を編集するためにgradleタスクを作成しましたが、ほとんどの場合は機能しているようです。コンパイルする必要のあるすべてのjarを取得し、バージョン情報やスラッシュを含まないように名前を変更します。次に、ファイルは:
で区切られた文字列に連結されます。
tasks.withType(JavaCompile) {
delete { delete '/tmp/gradle' }
copy {
from configurations.compile + configurations.testCompile
into '/tmp/gradle'
rename '(.*)-[0-9]+\\..*.jar', '$1.jar'
rename { String fileName -> fileName.replace("-", "") }
}
options.compilerArgs += ['--module-path', fileTree(dir: '/tmp/gradle', include: '*.jar').getFiles().join(':')]
}
当然、rx
ライブラリはパッケージ名の一部を共有します...しかし、これによりコンパイラは次のようなエラーを吐き出します:
error: module reads package rx.subscriptions from both rxjava and rxjavafx
error: module reads package rx.schedulers from both rxjava and rxjavafx
error: module reads package rx.observables from both rxjava and rxjavafx
error: module rxjava reads package rx.subscriptions from both rxjavafx and rxjava
error: module rxjava reads package rx.schedulers from both rxjavafx and rxjava
error: module rxjava reads package rx.observables from both rxjavafx and rxjava
error: module rxjavafx reads package rx.subscriptions from both rxjava and rxjavafx
error: module rxjavafx reads package rx.schedulers from both rxjava and rxjavafx
error: module rxjavafx reads package rx.observables from both rxjava and rxjavafx
この問題を回避する唯一の方法は、rxjava
とrxjavafx
の内容を単一のjarに再パッケージし、それを単一のモジュールとして追加することだと思われます。しかし、これは良い解決策ではないようです...
だから私の質問は:
注:標準のJava
/javac
でこれを実行しようとしましたが、同じ問題が発生します。また、ここに私のJava version:
Java version "9-ea"
Java(TM) SE Runtime Environment (build 9-ea+140)
Java HotSpot(TM) 64-Bit Server VM (build 9-ea+140, mixed mode)
新しいモジュールシステムを正しく使用していますか?
はい。表示されているのは意図した動作です。これは、JPMSモジュールでは分割パッケージが許可されていないためです。
「分割パッケージ」という用語に慣れていない場合、本質的には、2つの異なるモジュールからの同じパッケージの2つのメンバーを意味します。
例えば:
com.foo.A(moduleA.jarから)
com.foo.B(moduleB.jarから)
このエラーについて何ができますか?
次の2つのオプションがあります。
これらの依存関係によって更新が妨げられますか、それともrxがライブラリを更新するのを待つ必要がありますか?
Rxが最終的にlibを更新して、将来のある時点で分割パッケージを持たないことを願っています。それまでは、2つのjarを1つのjarに粉砕することをお勧めします(オプション#2)。
私は簡単な問題がありました:
error: module flyway.core reads package javax.transaction.xa from both jboss.transaction.api.1.2.spec and Java.sql
error: module slf4j.api reads package javax.transaction.xa from both jboss.transaction.api.1.2.spec and Java.sql
error: module hibernate.core reads package javax.transaction.xa from both jboss.transaction.api.1.2.spec and Java.sql
.../src/main/Java/module-info.Java:1: error: module eu.com.x reads package javax.transaction.xa from both Java.sql and jboss.transaction.api.1.2.spec
プロジェクトの推移的な依存関係(「gradleの依存関係」または「mvnの依存関係:ツリー」が役立つ場合があります)を確認し、次のようなコードで除外することで、分割パッケージのコンパイルの問題を取り除くことができます。
configurations.all {
exclude group: 'org.jboss.spec.javax.transaction', module: 'jboss-transaction-api_1.2_spec'
}
または
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.10.Final</version>
<exclusions>
<exclusion>
<groupId>org.jboss.spec.javax.transaction</groupId>
<artifactId>jboss-transaction-api_1.2_spec</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
私の問題では、jarの再パッケージ化は必要ありませんでした。この問題は、#JDK8では発生していません。おそらく依存関係を除外しても、すべてのプロジェクトで役立つとは限りません。
私は、java.transaction.xaがjavaeeとJava.transaction.xaの両方からパッケージを読み込むという同じ問題に直面しています。そして、この行をmodul-info.Javaに追加して修正しました
opens javax.transaction.xa;
正常に動作しましたが、パッケージjavax.transaction.xaが空であるか存在しないというヒントが表示されました。ただし、ソースコードは正しくコンパイルされます。