El paquete entra en conflicto con los módulos automáticos en Java 9

Con Java 9 en el horizonte cercano pensé que sería un buen ejercicio de aprendizaje trasladar algunos de mis proyectos a Java 9. En uno de mis proyectos tengo dependencias para rxjava y rxjavafx

dependencies { compile 'io.reactivex:rxjava:1.2.6' compile 'io.reactivex:rxjavafx:1.0.0' ... } 

Quiero crear este proyecto como un módulo nombrado. Para hacer esto, necesito crear un archivo module-info.java y necesito especificar los requisitos para rxjava y rxjavafx aquí. Sin embargo, estas libs no tienen ninguna información de módulo todavía.

Para solucionar este problema, he leído que necesito crear módulos automáticos . Por lo que entiendo, necesito cambiar el nombre de los rxjava y rxjavafx para tener un nombre simple y luego enumerar los --module-path en el parámetro --module-path . Luego agrego una directiva requires en mi module-info.java con los nombres jar.

 module com.foo.bar { requires rxjavafx; requires rxjava; } 

Escribí una tarea gradle para editar los nombres de jar para mí, y parece estar funcionando en la mayoría de los casos. Toma todas las jarras que necesitan ser comstackdas y las renombra para que no incluyan la información de la versión o las barras diagonales. Los archivos se concatenan en una cadena separada:

 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(':')] } 

Naturalmente, las bibliotecas rx comparten algunos de sus nombres de paquete … sin embargo, esto hace que el comstackdor escuche errores tales como:

 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 

Parece que la única forma de evitar este problema sería volver a empaquetar los contenidos de rxjava y rxjavafx en un único rxjavafx y agregarlo como un único módulo. Aunque esto no parece una buena solución …

Entonces mis preguntas son:

  • ¿Estoy usando el nuevo sistema de módulos correctamente?
  • ¿Qué puedo hacer con este error? y
  • ¿Estas dependencias me impiden actualizar, o debería esperar a que rx actualice sus libs?

Nota: He intentado ejecutar esto con java / javac estándar y causan los mismos problemas. También aquí está mi versión java:

 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) 

¿Estoy usando el nuevo sistema de módulos correctamente?

Sí. Lo que está viendo es el comportamiento previsto, y esto se debe a que los módulos JPMS no permiten paquetes divididos.

En caso de que no esté familiarizado con el término “paquetes divididos”, esencialmente significa que dos miembros del mismo paquete provienen de dos módulos diferentes.

Por ejemplo:
com.foo.A (desde el módulo A.jar)
com.foo.B (del módulo B.jar)

¿Qué puedo hacer con este error?

Tienes dos opciones:

  1. (más difícil) “no dividir” las dependencias del paquete. Sin embargo, esto podría ser difícil o imposible si no está familiarizado con el funcionamiento interno de la biblioteca
  2. (más fácil) combine los dos flasks en un solo flask (y, por lo tanto, un único módulo automático) como mencionó anteriormente. Estoy de acuerdo en que no es una “buena” solución, pero tener paquetes divididos desde el principio tampoco es una buena idea.

¿Estas dependencias me impiden actualizar, o debería esperar a que rx actualice sus libs?

Es de esperar que rx eventualmente actualice sus libs para no tener paquetes divididos en algún momento en el futuro. Hasta entonces, mi recomendación sería simplemente aplastar los dos flasks en un solo flask (opción n. ° 2).

Tuve un problema similar:

 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 

Podría deshacerme del problema de comstackción de paquetes divididos comprobando las dependencias transitivas de mi proyecto (“dependencias de gradle” o “dependencia mvn: árbol” podría ser útil) y excluir por código simmiliar a:

 configurations.all { exclude group: 'org.jboss.spec.javax.transaction', module: 'jboss-transaction-api_1.2_spec' } 

o

   org.hibernate hibernate-core 5.2.10.Final   org.jboss.spec.javax.transaction jboss-transaction-api_1.2_spec     

No era necesario reempaquetar el flask en mi problema. Este problema no se ha producido en # JDK8. Probablemente excluir dependencias no ayuda en todos los proyectos.