web-dev-qa-db-fra.com

Comment accéder à javax.annotation.Resource lors de l'exécution en Java 9

J'ai un contrôle:

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 fonctionnait, mais en Java 9 (j'utilise Oracle JDK 9), il échoue avec ClassNotFoundException. Comme expliqué ici Spring: l’injection @Resource a cessé de fonctionner 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 au module Java.xml.ws.annotation (qui contient javax.annotation.Resource). Mais le test échoue toujours.

Lorsque je supprime cette clause requires et ajoute une dépendance (en tant que bibliothèque) contenant javax.annotations.Resource, cela fonctionne:

    <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 Maven dans pom.xml et 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 toujours!

Si j'ajoute le module Java.xml.ws.annotation via la ligne de commande, cela fonctionne (sans dépendance Maven et clause withrequires):

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

Est-ce que je fais quelque chose de mal avec la description de mon module? Comment puis-je accéder au javax.annotation.Resource fourni par JDK sans les commutateurs de ligne de commande?

Le projet de test est disponible sur https://github.com/rpuch/test-resource-jdk9

17
Roman Puchkovskiy

Juste pour effacer une certaine confusion ici. Les méthodes de travail énoncées dans la question par vous sont des alternatives et ne doivent pas être combinées comme vous l'avez déjà vu.

le module non nommé lit le package javax.annotation à partir de deux 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 le javax.xml.ws.annotation comme module pouvant être mis à jour qui est le moment où vous pouvez utiliser la dépendance

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

Dans l’idéal, c’est une option préférable, car l’ancien n’est qu’une alternative à l’utilisation du module @Deprecated marqué forRemoval.


Ainsi, la clause requise en elle-même ne suffit pas pour avoir accès à un module ... est-ce vrai pour tous les modules fournis par JDK (à l'exception de Java.base), ou seulement pour les modules obsolètes?

Non, la requires n'est qu'une partie de la déclaration. [Réfléchissez à cela avant la JDK 9 si vous utilisiez une instruction import some.foo.bar; dans votre classe qui n'était pas ajoutée en tant que bibliothèque (classpath) aurait-elle fonctionné?]. Le module marqué comme requis doit figurer sur le modulepath pour que vous puissiez y accéder.


Update - La première option ne serait plus supportée avec l'utilisation de JDK/11 ou une version ultérieure dans laquelle le PEC pour Supprimer les modules Java EE et CORBA est ciblé.

25
nullpointer

Pour construire gradle, ajouter ce qui suit à 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"]
}
1
Pratik Patil