如何在 Java 9 中在运行时访问 javax.annotation.Resource

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/46502001/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 02:23:14  来源:igfitidea点击:

How to get access to javax.annotation.Resource at run time in Java 9

javajava-9java-module

提问by Roman Puchkovskiy

I have a test:

我有一个测试:

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

It tries to access javax.annotation.Resource. In java 8 it worked, but in java 9 (I'm using Oracle JDK 9) it fails with ClassNotFoundException. As explained here Spring: @Resource injection stopped working under JDK9, javax.annotation.Resourcefrom the JDK is not available by default in Java 9.

它尝试访问javax.annotation.Resource. 在 java 8 中它有效,但在 java 9(我使用的是 Oracle JDK 9)中它失败了ClassNotFoundException。正如此处所解释的Spring:@Resource 注入在 JDK9 下停止工作javax.annotation.Resource来自 JDK 的默认情况下在 Java 9 中不可用。

I'm trying to get access to it using module descriptor:

我正在尝试使用模块描述符访问它:

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

Here, I specifically request access to java.xml.ws.annotationmodule (which contains javax.annotation.Resource). But the test still fails.

在这里,我特别请求访问java.xml.ws.annotation模块(其中包含javax.annotation.Resource)。但测试仍然失败。

When I remove that requiresclause and add a dependency (as a library) which contains javax.annotations.Resource, it works:

当我删除该requires子句并添加包含 的依赖项(作为库)时javax.annotations.Resource,它可以工作:

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

When I add them both (Maven dependency in pom.xmland requires java.xml.ws.annotation), compilation in IDEA fails with the following message:

当我同时添加它们(Maven 依赖于pom.xmlrequires java.xml.ws.annotation)时,IDEA 中的编译失败并显示以下消息:

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

But Maven build still succeeds!

但是Maven构建仍然成功!

If I add java.xml.ws.annotationmodule via command line, it works (with no Maven dependency and withrequiresclause):

如果我java.xml.ws.annotation通过命令行添加模块,它就可以工作(没有 Maven 依赖和withrequires子句):

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

Do I do something wrong with my module description? How can I get access to JDK-supplied javax.annotation.Resourcewithout command line switches?

我的模块描述有问题吗?如何在javax.annotation.Resource没有命令行开关的情况下访问 JDK 提供的?

The test project is available at https://github.com/rpuch/test-resource-jdk9

测试项目可在https://github.com/rpuch/test-resource-jdk9 获得

采纳答案by Naman

Just to clear out some confusion here. The ways to work stated in the question by you are alternatives and should not be combined as you have already seen.

只是为了清除这里的一些混乱。您在问题中陈述的工作方式是替代方案,不应像您已经看到的那样结合使用。

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

未命名模块从 java.xml.ws.annotation 和 java.annotation 读取包 javax.annotation



So the way it would work is either:

所以它的工作方式是:

You can use the compiler args to add 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>

OR

或者

Make use of the javax.xml.ws.annotationbeing an upgradeable modulewhich is when you can make use of the dependency

利用的javax.xml.ws.annotation是一个升级模块是当你可以使用依赖

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

Ideally this would be a preferrable option to stick to as the former is just an alternate to use the @Deprecatedmodule marked forRemoval.

理想情况下,这将是一个更好的选择,因为前者只是使用标记为@Deprecated模块的替代方法forRemoval



So the required clause by itself it not enough to get access to a module... is this true for all JDK-supplied modules (excluding java.base), or it is only true for deprecated modules?

所以 required 子句本身不足以访问模块......对于所有JDK提供的模块(不包括java.base)都是如此,还是只对不推荐使用的模块如此?

No, the requiresis just a part of declaration. [Think about this, prior to JDK 9 if you used a statement import some.foo.bar;in your class which was not added as a library(classpath) would that have worked?]. The module marked as required has to be on the modulepath for you to access it.

不,这requires只是声明的一部分。[考虑一下,在 JDK 9 之前,如果您import some.foo.bar;在类中使用了未添加为库(类路径)的语句,那会起作用吗?]。标记为必需的模块必须在模块路径上才能访问它。



Update- The first option would not be supported any time longer with the use of JDK/11 or above wherein the JEP to Remove the Java EE and CORBA Modulesis targetted.

更新- 使用 JDK/11 或更高版本将不再支持第一个选项,其中以删除 Java EE 和 CORBA 模块的 JEP 为目标。

回答by Pratik Patil

For gradle build, adding the following to build.gradle works:

对于 gradle 构建,将以下内容添加到 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"]
}