Как получить доступ к javax.аннотация.Ресурсов во время выполнения в Java 9

у меня есть тест:

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

пытается получить доступ к javax.annotation.Resource. В java 8 он работал, но в java 9 (я использую Oracle JDK 9) он терпит неудачу с ClassNotFoundException. Как объясняется здесь Весна: @ впрыска ресурса остановила работать под JDK9 , javax.annotation.Resource из JDK недоступен по умолчанию в Java 9.

я пытаюсь получить доступ к нему с помощью дескриптора модуля:

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

здесь я специально запрашиваю доступ к (который содержит javax.annotation.Resource). Но тест все равно проваливается.

когда я удалить requires предложение и добавить зависимость (как библиотеку), которая содержит javax.annotations.Resource, работает:

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

когда я добавляю их обоих (зависимость Maven в pom.xml и requires java.xml.ws.annotation), компиляция в IDEA завершается со следующим сообщением:

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

но Maven build все еще преуспевает!

если я добавить java.xml.ws.annotation модуль через командную строку, он работает (без зависимости Maven и С requires пункта):

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

я делаю что-то не так с моим описанием модуля? Как я могу получить доступ к JDK-supplied javax.annotation.Resource без параметров командной строки?

тестовый проект доступен по адресу https://github.com/rpuch/test-resource-jdk9

2 ответов


просто зачистить какая-то путаница. Способы работы, изложенные в вопросе вами, являются альтернативами и не должны объединяться, как вы уже видели.

неназванный модуль считывает пакет javax.аннотация от обоих Ява.в формате XML.с WS.аннотации и Java.аннотация


таким образом, это будет работать либо:

вы можете использовать args компилятора для добавления модулей

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

или

использовать javax.xml.ws.annotation являясь обновляемый модуль когда вы можете использовать зависимость

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

В идеале это было бы предпочтительным вариантом, чтобы придерживаться, поскольку первый является просто альтернативой для использования @Deprecated модуль, отмеченные forRemoval.


таким образом, требуемое предложение само по себе недостаточно, чтобы получить доступ к модуль... это правда для всех модулей, поставляемых JDK (исключая Ява.base), или это верно только для устаревших модулей?

нет,requires это просто часть декларации. [Подумайте об этом, до JDK 9, Если вы использовали оператор import some.foo.bar; в вашем классе, который не был добавлен в качестве библиотеки (classpath), это сработало бы?]. Модуль, отмеченный как требуется, должен быть на modulepath для доступа к нему.


обновление - первый вариант не поддерживается в любое время с использованием JDK / 11 или выше, где JEP для удалите модули Java EE и CORBA рассчитана.


для сборки gradle добавьте следующее Для сборки.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"]
}