Avec Java 9 à l'horizon proche, je pensais que ce serait un bon exercice d'apprentissage de porter certains de mes projets sur Java 9. Dans l'un de mes projets) J'ai des dépendances pour rxjava et rxjavafx
dependencies {
compile 'io.reactivex:rxjava:1.2.6'
compile 'io.reactivex:rxjavafx:1.0.0'
...
}
Je veux créer ce projet en tant que module nommé. Pour ce faire, je dois créer un module-info.Java
fichier et je dois spécifier les exigences pour rxjava
et rxjavafx
ici. Cependant, ces bibliothèques n'ont pas encore d'informations sur le module.
Afin de contourner cela, j'ai lu que j'ai besoin de créer des modules automatiques . D'après ce que je comprends, je dois renommer les bocaux rxjava
et rxjavafx
pour avoir un nom simple, puis répertorier les bocaux dans le --module-path
paramètre. J'ajoute ensuite une directive requires
dans mon module-info.Java
avec les noms des pots.
module com.foo.bar {
requires rxjavafx;
requires rxjava;
}
J'ai écrit une tâche gradle pour modifier les noms des pots pour moi, et cela semble fonctionner dans la plupart des cas. Il prend tous les fichiers jar qui doivent être compilés et les renomme pour ne pas inclure les informations de version ou les barres obliques. Les fichiers sont ensuite concaténés dans un :
chaîne séparée:
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(':')]
}
Naturellement, les bibliothèques rx
partagent certains de leurs noms de packages ... cela provoque cependant le compilateur à cracher des erreurs telles que:
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
Il semble que la seule façon de contourner ce problème serait de reconditionner le contenu de rxjava
et rxjavafx
dans un seul pot et de l'ajouter en tant que module unique. Cela ne semble cependant pas être une bonne solution ...
Mes questions sont donc:
Remarque: J'ai essayé de l'exécuter avec le standard Java
/javac
et ils causent les mêmes problèmes. Voici également mon 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)
Suis-je en train d'utiliser correctement le nouveau système de modules?
Oui. Ce que vous voyez, c'est le comportement voulu, et c'est parce que les modules JPMS n'autorisent pas les packages fractionnés.
Dans le cas où vous n'êtes pas familier avec le terme "packages séparés", cela signifie essentiellement deux membres du même package provenant de deux modules différents.
Par exemple:
com.foo.A (à partir du moduleA.jar)
com.foo.B (à partir du moduleB.jar)
Que puis-je faire à propos de cette erreur?
Vous avez deux options:
Ces dépendances m'empêchent-elles de mettre à jour, ou dois-je simplement attendre que rx mette à jour leurs bibliothèques?
Avec un peu de chance, rx mettra éventuellement à jour ses bibliothèques pour ne pas avoir de packages séparés à un moment donné dans le futur. Jusque-là, ma recommandation serait de casser les deux pots ensemble dans un seul pot (option n ° 2).
J'ai eu un problème similaire:
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
Je pourrais me débarrasser du problème de compilation des packages fractionnés en vérifiant les dépendances transitives de mon projet ("dépendances gradle" ou "dépendance mvn: arbre" pourrait être utile) et en excluant par code simmiliar:
configurations.all {
exclude group: 'org.jboss.spec.javax.transaction', module: 'jboss-transaction-api_1.2_spec'
}
ou
<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>
Aucun reconditionnement de bocal n'était nécessaire dans mon problème. Ce problème ne s'est pas produit sur # JDK8. L'exclusion probable des dépendances n'aide pas dans tous les projets.
j'ai été confronté au même problème avec le package de lecture Java.transaction.xa de javaee et Java.transaction.xa. Et je l'ai corrigé en ajoutant cette ligne à mon modul-info.Java
opens javax.transaction.xa;
Cela a bien fonctionné mais un indice est apparu indiquant que le package javax.transaction.xa est vide ou n'existe pas. cependant, le code source se compile correctement.