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:
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:
¿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.