wake-up-neo.net

So erhalten Sie zur Laufzeit in Java 9 Zugriff auf javax.annotation.Resource

Ich habe einen Test:

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

Es wird versucht, auf javax.annotation.Resource zuzugreifen. In Java 8 hat es funktioniert, aber in Java 9 (ich verwende Oracle JDK 9) schlägt es mit ClassNotFoundException fehl. Wie hier erläutert Spring: @Resource-Injektion funktioniert nicht mehr unter JDK9 , javax.annotation.Resource aus dem JDK ist in Java 9 standardmäßig nicht verfügbar.

Ich versuche, mithilfe des Moduldeskriptors darauf zuzugreifen:

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

Hier beantrage ich ausdrücklich den Zugriff auf das Java.xml.ws.annotation-Modul (das javax.annotation.Resource enthält). Aber der Test schlägt immer noch fehl.

Wenn ich die requires-Klausel entferne und eine Abhängigkeit (als Bibliothek) hinzufüge, die javax.annotations.Resource enthält, funktioniert es:

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

Wenn ich beide hinzufügen (Maven-Abhängigkeit in pom.xml und requires Java.xml.ws.annotation), schlägt die Kompilierung in IDEA mit der folgenden Meldung fehl:

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

Aber Maven Build ist immer noch erfolgreich!

Wenn ich Java.xml.ws.annotation-Modul über die Befehlszeile hinzufüge, funktioniert es (ohne Maven-Abhängigkeit und mitrequires-Klausel):

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

Mache ich etwas falsch mit meiner Modulbeschreibung? Wie kann ich ohne Befehlszeilenschalter auf den von JDK gelieferten javax.annotation.Resource zugreifen?

Das Testprojekt ist verfügbar unter https://github.com/rpuch/test-resource-jdk9 .

17

Nur um hier einige Verwirrung auszuräumen. Die von Ihnen in der Frage angegebenen Arbeitsweisen sind Alternativen und sollten nicht wie Sie bereits gesehen haben, miteinander kombiniert werden.

das unbenannte Modul liest das Paket javax.annotation von beiden Java.xml.ws.annotation und Java.annotation


So würde es funktionieren, entweder:

Sie können die Compiler-Argumente verwenden, um Module hinzuzufügen 

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

ODER

Verwenden Sie javax.xml.ws.annotation als aufrüstbares Modul , wenn Sie die Abhängigkeit nutzen können

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

Idealerweise wäre dies eine bevorzugte Option, an die man sich halten sollte, da die erstgenannte Variante nur das @Deprecated - Modul mit der Bezeichnung forRemoval verwenden kann.


Die erforderliche Klausel allein reicht also nicht aus, um auf eine .__ zuzugreifen. module ... ist dies für alle von JDK bereitgestellten Module (außer Java.base) oder nur für veraltete Module gültig?

Nein, das requires ist nur ein Teil der Deklaration. [Denken Sie darüber nach, bevor Sie JDK 9 verwenden, wenn Sie in Ihrer Klasse eine Anweisung import some.foo.bar; verwendet haben, die nicht als Bibliothek hinzugefügt wurde (classpath), was funktioniert hätte?]. Das als erforderlich gekennzeichnete Modul muss sich auf dem Modulpfad befinden, damit Sie darauf zugreifen können.


Update - Die erste Option wird bei Verwendung von JDK/11 oder höher nicht mehr unterstützt, wobei der JEP zum Entfernen der Java EE- und CORBA-Module angesteuert wird.

25
nullpointer

Für Gradle Build fügen Sie Folgendes zu build.gradle works hinzu:

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