20 votes

Comment obtenir l'accès à javax.annotation.Resource au moment de l'exécution en Java 9 ?

J'ai un test :

public class ResourceTest {
    @Test
    public void test() throws ClassNotFoundException {
        Class.forName("javax.annotation.Resource");
    }
}

Il essaie d'accéder javax.annotation.Resource . En java 8, cela a fonctionné, mais en java 9 (j'utilise Oracle JDK 9), il échoue avec ClassNotFoundException . Comme expliqué ici Printemps : L'injection de @Resource ne fonctionne plus sous JDK9 , javax.annotation.Resource du JDK n'est pas disponible par défaut dans Java 9.

J'essaie d'y accéder en utilisant le descripteur de module :

module test {
    requires java.xml.ws.annotation;
    requires junit;
}

Ici, je demande spécifiquement l'accès à java.xml.ws.annotation (qui contient javax.annotation.Resource ). Mais le test échoue toujours.

Quand j'enlève ça requires et ajouter une dépendance (en tant que bibliothèque) qui contient javax.annotations.Resource ça marche :

    <dependency>
        <groupId>javax.annotation</groupId>
        <artifactId>javax.annotation-api</artifactId>
        <version>1.3.1</version>
    </dependency>

Lorsque je les ajoute tous les deux (dépendance de Maven en pom.xml y requires java.xml.ws.annotation ), la compilation dans IDEA échoue avec le message suivant :

the unnamed module reads package javax.annotation from both java.xml.ws.annotation and java.annotation

Mais la construction de Maven réussit quand même !

Si j'ajoute java.xml.ws.annotation via la ligne de commande, cela fonctionne (sans dépendance Maven et avec avec requires clause) :

mvn clean test -DargLine="--add-modules java.xml.ws.annotation"

Ai-je fait quelque chose de mal dans la description de mon module ? Comment puis-je avoir accès aux modules fournis par le JDK ? javax.annotation.Resource sans commutateur de ligne de commande ?

Le projet de test est disponible à l'adresse suivante https://github.com/rpuch/test-resource-jdk9

29voto

nullpointer Points 1135

Juste pour dissiper une certaine confusion ici. Les méthodes de travail mentionnées dans votre question sont des alternatives et ne doivent pas être combinées, comme vous l'avez déjà constaté.

le module sans nom lit le paquetage javax.annotation à partir des deux éléments suivants java.xml.ws.annotation et java.annotation.


Donc la façon dont cela fonctionnerait est soit :

Vous pouvez utiliser les arguments du compilateur pour ajouter des modules.

<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>

OU

Utilisez l'outil javax.xml.ws.annotation être un module évolutif c'est alors que vous pouvez utiliser la dépendance

<dependency>
    <groupId>javax.annotation</groupId>
    <artifactId>javax.annotation-api</artifactId>
    <version>1.3.1</version>
</dependency>

Idéalement, il serait préférable de s'en tenir à cette option, car la première n'est qu'une alternative à l'utilisation de l'option @Deprecated module marqué forRemoval .


Ainsi, la clause requise ne suffit pas à elle seule à obtenir l'accès à un... module... est-ce vrai pour tous les modules fournis par le JDK (à l'exception de java.base), ou cela n'est vrai que pour les modules dépréciés ?

Non, le requires est juste une partie de la déclaration. [Pensez-y, avant le JDK 9, si vous utilisiez une déclaration import some.foo.bar; dans votre classe qui n'a pas été ajoutée comme bibliothèque (classpath), cela aurait-il fonctionné ?]. Le module marqué comme requis doit se trouver dans le modulepath pour que vous puissiez y accéder.


Mise à jour - La première option n'est plus prise en charge avec l'utilisation de JDK/11 ou supérieur, dans lequel le JEP à Supprimer les modules Java EE et CORBA est ciblée.

2voto

Pratik Patil Points 1683

Pour la construction de gradle, l'ajout de ce qui suit à build.gradle fonctionne :

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"]
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X