operator - Cómo obtener acceso a javax.annotation.Resource en tiempo de ejecución en Java 9
java modulus operator (2)
Para la construcción de Gradle, agregando lo siguiente a los trabajos de build.gradle:
compile ''javax.annotation:jsr250-api:1.0''
tasks.withType(AbstractCompile) {
options.compilerArgs += ["--add-modules", "java.xml.bind"]
}
tasks.withType(Test) {
jvmArgs += ["--add-modules", "java.xml.bind"]
}
Tengo un examen:
public class ResourceTest {
@Test
public void test() throws ClassNotFoundException {
Class.forName("javax.annotation.Resource");
}
}
Intenta acceder a javax.annotation.Resource
. En Java 8 funcionó, pero en Java 9 (estoy usando Oracle JDK 9) falla con ClassNotFoundException
. Como se explicó aquí Spring: @Resource La inyección dejó de funcionar bajo JDK9 , javax.annotation.Resource
del JDK no está disponible de forma predeterminada en Java 9.
Estoy tratando de acceder a él usando el descriptor de módulo:
module test {
requires java.xml.ws.annotation;
requires junit;
}
Aquí, solicito específicamente el acceso al módulo java.xml.ws.annotation
(que contiene javax.annotation.Resource
). Pero la prueba sigue fallando.
Cuando elimino eso, requires
cláusula y añado una dependencia (como una biblioteca) que contiene javax.annotations.Resource
, funciona:
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.1</version>
</dependency>
Cuando los agrego a ambos (la dependencia de Maven en pom.xml
y requires java.xml.ws.annotation
), la compilación en IDEA falla con el siguiente mensaje:
the unnamed module reads package javax.annotation from both java.xml.ws.annotation and java.annotation
¡Pero la construcción de Maven todavía tiene éxito!
Si java.xml.ws.annotation
módulo java.xml.ws.annotation
través de la línea de comandos, funciona (sin dependencia de Maven y con cláusula de java.xml.ws.annotation
):
mvn clean test -DargLine="--add-modules java.xml.ws.annotation"
¿Hago algo mal con la descripción de mi módulo? ¿Cómo puedo obtener acceso a javax.annotation.Resource
provisto por javax.annotation.Resource
sin interruptores de línea de comando?
El proyecto de prueba está disponible en https://github.com/rpuch/test-resource-jdk9
Solo para aclarar algo de confusión aquí. Las formas de trabajar establecidas en la pregunta por usted son alternativas y no deben combinarse como ya ha visto.
el módulo sin nombre lee el paquete javax.annotation de java.xml.ws.annotation y java.annotation
Así que la forma en que funcionaría es:
Puedes usar los argumentos del compilador para agregar módulos
<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>
O
Utilice javax.xml.ws.annotation
como un módulo actualizable que es cuando puede hacer uso de la dependencia
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.1</version>
</dependency>
Idealmente, esta sería una opción preferible a seguir, ya que la primera es solo una alternativa para usar el módulo forRemoval
marcado para forRemoval
.
Entonces, la cláusula requerida por sí sola no es suficiente para obtener acceso a un módulo ... ¿es esto cierto para todos los módulos provistos por JDK (excluyendo java.base), o solo es cierto para módulos en desuso?
No, el requires
es solo una parte de la declaración. [Piense en esto, antes de JDK 9 si usó una declaración import some.foo.bar;
en tu clase que no se agregó como una biblioteca (classpath), ¿habría funcionado?]. El módulo marcado como requerido debe estar en el modulepath para que pueda acceder a él.
Actualización : la primera opción no se admitirá durante más tiempo con el uso de JDK / 11 o superior, en el que el JEP para eliminar los módulos Java EE y CORBA está dirigido.