如何在 Java 的 运行 时间访问 javax.annotation.Resource 9
How to get access to javax.annotation.Resource at run time in 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
。
如此处 所述,JDK 中的 javax.annotation.Resource
在 Java 9.
中默认不可用
我正在尝试使用模块描述符访问它:
module test {
requires java.xml.ws.annotation;
requires junit;
}
在这里,我特别请求访问 java.xml.ws.annotation
模块(其中包含 javax.annotation.Resource
)。但是测试还是失败了。
当我删除 requires
子句并添加包含 javax.annotations.Resource
的依赖项(作为库)时,它起作用了:
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.1</version>
</dependency>
当我同时添加它们时(pom.xml
和 requires java.xml.ws.annotation
中的 Maven 依赖项),IDEA 中的编译失败并显示以下消息:
the unnamed module reads package javax.annotation from both java.xml.ws.annotation and java.annotation
但是Maven构建还是成功了!
如果我通过命令行添加 java.xml.ws.annotation
模块,它可以工作(没有 Maven 依赖项和 with requires
子句):
mvn clean test -DargLine="--add-modules java.xml.ws.annotation"
我的模块描述有问题吗?如何在没有命令行开关的情况下访问 JDK 提供的 javax.annotation.Resource
?
只是为了澄清这里的一些混乱。您在问题中所述的工作方式是替代方案,不应像您已经看到的那样合并。
the unnamed module reads package javax.annotation from both
java.xml.ws.annotation and java.annotation
所以它的工作方式是:
您可以使用编译器参数添加模块
<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
作为 upgradeable module,这样您就可以利用依赖性
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.1</version>
</dependency>
理想情况下,这将是一个更可取的选择,因为前者只是使用标记为 forRemoval
的 @Deprecated 模块的替代方法。
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?
不,requires
只是声明的一部分。 [想想这个,在 JDK 9 之前,如果你在你的 class 中使用了一个语句 import some.foo.bar;
而不是作为库(class 路径)添加,那会有效吗? ].标记为必需的模块必须位于模块路径上,您才能访问它。
Update - 使用 JDK/11 或更高版本将不再支持第一个选项,其中Remove the Java EE and CORBA Modules 的 JEP 是目标。
对于 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"]
}
我有一个测试:
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
。
如此处 javax.annotation.Resource
在 Java 9.
我正在尝试使用模块描述符访问它:
module test {
requires java.xml.ws.annotation;
requires junit;
}
在这里,我特别请求访问 java.xml.ws.annotation
模块(其中包含 javax.annotation.Resource
)。但是测试还是失败了。
当我删除 requires
子句并添加包含 javax.annotations.Resource
的依赖项(作为库)时,它起作用了:
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.1</version>
</dependency>
当我同时添加它们时(pom.xml
和 requires java.xml.ws.annotation
中的 Maven 依赖项),IDEA 中的编译失败并显示以下消息:
the unnamed module reads package javax.annotation from both java.xml.ws.annotation and java.annotation
但是Maven构建还是成功了!
如果我通过命令行添加 java.xml.ws.annotation
模块,它可以工作(没有 Maven 依赖项和 with requires
子句):
mvn clean test -DargLine="--add-modules java.xml.ws.annotation"
我的模块描述有问题吗?如何在没有命令行开关的情况下访问 JDK 提供的 javax.annotation.Resource
?
只是为了澄清这里的一些混乱。您在问题中所述的工作方式是替代方案,不应像您已经看到的那样合并。
the unnamed module reads package javax.annotation from both java.xml.ws.annotation and java.annotation
所以它的工作方式是:
您可以使用编译器参数添加模块
<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
作为 upgradeable module,这样您就可以利用依赖性
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.1</version>
</dependency>
理想情况下,这将是一个更可取的选择,因为前者只是使用标记为 forRemoval
的 @Deprecated 模块的替代方法。
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?
不,requires
只是声明的一部分。 [想想这个,在 JDK 9 之前,如果你在你的 class 中使用了一个语句 import some.foo.bar;
而不是作为库(class 路径)添加,那会有效吗? ].标记为必需的模块必须位于模块路径上,您才能访问它。
Update - 使用 JDK/11 或更高版本将不再支持第一个选项,其中Remove the Java EE and CORBA Modules 的 JEP 是目标。
对于 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"]
}