我有一个测试:
public class ResourceTest {
@Test
public void test() throws ClassNotFoundException {
Class.forName("javax.annotation.Resource");
}
}
Run Code Online (Sandbox Code Playgroud)
它试图访问javax.annotation.Resource.在java 8中它可以工作,但是在java 9中(我使用的是Oracle JDK 9)它失败了ClassNotFoundException.正如本文所解释的那样:@Resource注入在JDK9下停止工作,javax.annotation.ResourceJDK在Java 9中默认不可用.
我正在尝试使用模块描述符访问它:
module test {
requires java.xml.ws.annotation;
requires junit;
}
Run Code Online (Sandbox Code Playgroud)
在这里,我特意请求访问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>
Run Code Online (Sandbox Code Playgroud)
当我同时添加它们(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
Run Code Online (Sandbox Code Playgroud)
但Maven构建仍然成功!
如果我java.xml.ws.annotation通过命令行添加模块,它可以工作(没有Maven依赖和with requires子句):
mvn clean test …Run Code Online (Sandbox Code Playgroud) 根据这个关于Java 9的新版本字符串方案的博客,该版本应该是,例如MAJOR.MINOR.SECURITY,应该有3个数字和2个句点.
但是,使用Azul的Zulu 9,当我打印Java版本时,它有4个数字和3个句点:
./jdk/bin/java -version
openjdk version "9.0.0.15"
OpenJDK Runtime Environment (Zulu build 9.0.0.15+181)
OpenJDK 64-Bit Server VM (Zulu build 9.0.0.15+181, mixed mode)
Run Code Online (Sandbox Code Playgroud)
4个数字代表什么?
我的Eclipse RCP Maven项目使用Java 8构建得很好,但是在Java 9中失败了:
[INFO] Scanning for projects...
[WARNING] Could not start bundle org.eclipse.equinox.registry
org.osgi.framework.BundleException: Could not resolve module: org.eclipse.equinox.registry [42]
Unresolved requirement: Require-Bundle: org.eclipse.equinox.common; bundle-version="[3.7.0,4.0.0)"
-> Bundle-SymbolicName: org.eclipse.equinox.common; bundle-version="3.8.0.v20160315-1450"; singleton:="true"
org.eclipse.equinox.common [18]
Unresolved requirement: Require-Capability: osgi.ee; filter:="(&(osgi.ee=JavaSE)(version=1.7))"
Unresolved requirement: Import-Package: org.eclipse.core.runtime.jobs; resolution:="optional"
-> Export-Package: org.eclipse.core.runtime.jobs; bundle-symbolic-name="org.eclipse.core.jobs"; bundle-version="3.8.0.v20160209-0147"; version="0.0.0"
org.eclipse.core.jobs [6]
Unresolved requirement: Require-Bundle: org.eclipse.equinox.common; bundle-version="[3.8.0,4.0.0)"
-> Bundle-SymbolicName: org.eclipse.equinox.common; bundle-version="3.8.0.v20160315-1450"; singleton:="true"
at org.eclipse.osgi.container.Module.start(Module.java:434)
at org.eclipse.osgi.internal.framework.EquinoxBundle.start(EquinoxBundle.java:392)
at org.eclipse.sisu.equinox.embedder.internal.DefaultEquinoxEmbedder.tryActivateBundle(DefaultEquinoxEmbedder.java:215)
at org.eclipse.sisu.equinox.embedder.internal.DefaultEquinoxEmbedder.activateBundlesInWorkingOrder(DefaultEquinoxEmbedder.java:207)
at org.eclipse.sisu.equinox.embedder.internal.DefaultEquinoxEmbedder.doStart(DefaultEquinoxEmbedder.java:182)
at org.eclipse.sisu.equinox.embedder.internal.DefaultEquinoxEmbedder.start(DefaultEquinoxEmbedder.java:67)
at org.eclipse.sisu.equinox.embedder.internal.DefaultEquinoxEmbedder.checkStarted(DefaultEquinoxEmbedder.java:310)
at org.eclipse.sisu.equinox.embedder.internal.DefaultEquinoxEmbedder.getService(DefaultEquinoxEmbedder.java:286)
at org.eclipse.sisu.equinox.embedder.internal.DefaultEquinoxEmbedder.getService(DefaultEquinoxEmbedder.java:280) …Run Code Online (Sandbox Code Playgroud) 我们使用maven并拥有依赖于其他内部工件的工件.我正在迁移到java-9,并且打算首先将所有内容迁移到Java 9而不模块化代码(即在未命名的模块中).
我遇到的问题是我们依赖java.xml.bind,现在不包含在默认模块中.是否有一种"正确"的方式来表达对java.xml.bindMaven的依赖?
我的项目依赖于Netty Epoll传输.这是依赖:
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-transport-native-epoll</artifactId>
<version>${netty.version}</version>
<classifier>${epoll.os}</classifier>
</dependency>
Run Code Online (Sandbox Code Playgroud)
此依赖项的自动生成的模块名称为:
netty.transport.native.epoll
Run Code Online (Sandbox Code Playgroud)
由于native关键字是在Java 9中保留的,我无法将此模块作为依赖项添加到我的项目中:
module core {
requires netty.transport.native.epoll;
}
Run Code Online (Sandbox Code Playgroud)
由于:
module not found: netty.transport.<error>
Run Code Online (Sandbox Code Playgroud)
此外,jar工具--describe-module报告以下内容:
无法导出模块描述符:网状输送本地-epoll的-4.1.17.Final-快照Linux的x86_64.jar netty.transport.native.epoll:无效的模块名称:"天然"是不是Java标识符
有没有解决方法?(当然,除了"发布正确的网络工件").
编辑:
作为维护者的快速修复 - 您可以添加下一行来构建:
<manifestEntries>
<Automatic-Module-Name>netty.transport.epoll</Automatic-Module-Name>
</manifestEntries>
Run Code Online (Sandbox Code Playgroud) 在Java 8之前,SunPKCS11提供程序的加载方式如下:
Provider provider = new sun.security.pkcs11.SunPKCS11 (new ByteArrayInputStream (configFile.getBytes ()));
Security.addProvider (provider);
Run Code Online (Sandbox Code Playgroud)
configFile是带有配置参数的String.因此,如果应用程序需要使用多个连接的智能卡,它可以创建多个提供程序.要访问每个提供程序,使用的名称是"SunPKCS11-",后跟我们在配置中指示的名称.
在Java 8中,sun.security.pkcs11.SunPKCS11该类已在JDK中删除.所以,我不得不通过反思来编程前一个调用.
Java 9中PKCS#11提供程序的操作似乎非常不同:
该SunPKCS11构造已更改为空单.配置由"configure"方法加载,因此必须将它放在磁盘上的文件中,我不能再通过流将其加载到字符串.
如果我们尝试使用反射,则会出现以下警告:
Run Code Online (Sandbox Code Playgroud)WARNING: An illegal reflective access operation has occurred WARNING: Illegal reflective access by PruebaTarjeta (file:/C:/temp/pkcs11java9/classes/) to constructor sun.security.pkcs11.SunPKCS11() WARNING: Please consider reporting this to the maintainers of PruebaTarjeta WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations WARNING: All illegal access operations will be denied in a future release
以下代码使用Java 8编译,但不编译Java 9:
public class CompileErrJdk9 {
@FunctionalInterface public interface Closure<R> {
R apply();
}
@FunctionalInterface public interface VoidClosure {
void apply();
}
static <R> R call(Closure<R> closure) {
return closure.apply();
}
static void call(VoidClosure closure) {
call(() -> { closure.apply(); return null; });
}
static <T> void myMethod(T data) {
System.out.println(data);
}
public static void main(String[] args) {
call(() -> myMethod("hello")); //compile error in jdk9
}
}
Run Code Online (Sandbox Code Playgroud)
这是错误:
CompileErrJdk9.java:24: error: incompatible types: inference variable R has incompatible bounds
call(() …Run Code Online (Sandbox Code Playgroud) 我正在尝试将我们的一个系统从 java 8 移动到 java 9,并且大约三分之一在 java 8 中正常工作的单元测试失败并出现以下错误:
java.io.IOException: Can not attach to current VM
Run Code Online (Sandbox Code Playgroud)
Google 带我看了几页,我很快就明白在 Java 9 中,默认行为已更改,以防止附加到当前 VM 并返回到您需要将系统属性设置jdk.attach.allowAttachSelf为 true的旧方式。
在 IntelliJ 中设置时,测试工作正常。更改 build.gradle 以包含此内容时,同样有效:
test {
jvmArgs '-Djdk.attach.allowAttachSelf=true'
}
Run Code Online (Sandbox Code Playgroud)
但是,我更喜欢全局设置此设置,因此我不需要破解我的 build.gradle 和 IntelliJ。
我在 ubuntu 上运行 java 9 并更改/etc/profile.d/jdk.sh为包含以下内容:
export JDK_JAVA_OPTIONS="-Djdk.attach.allowAttachSelf=true"
Run Code Online (Sandbox Code Playgroud)
当运行我的 Gradle 构建时,我可以看到设置被拾取,因为我在构建输出中低于:
NOTE: Picked up JDK_JAVA_OPTIONS: -Djdk.attach.allowAttachSelf=true
Run Code Online (Sandbox Code Playgroud)
但是,测试不断失败,并出现相同的 IOException。
那么我做错了什么,我该如何解决?
预先感谢您的意见。
TLDR:在Java 9/10上,Tomcat中的Web应用程序无法访问JAXB,即使它的引用实现存在于类路径中.
编辑:不,这不是如何解决java.lang.NoClassDefFoundError:Java 9中的javax/xml/bind/JAXBException的副本- 正如您在"我尝试过的内容"部分所述,我已经尝试了所提出的解决方案.
我们有一个在Tomcat上运行的Web应用程序,它依赖于JAXB.在我们迁移到Java 9期间,我们选择将JAXB参考实现添加为常规依赖项.
从具有嵌入式Tomcat的IDE启动应用程序时,一切正常,但在真正的Tomcat实例上运行时,我收到此错误:
Caused by: java.lang.RuntimeException: javax.xml.bind.JAXBException:
Implementation of JAXB-API has not been found on module path or classpath.
- with linked exception:
[java.lang.ClassNotFoundException: com.sun.xml.internal.bind.v2.ContextFactory]
at [... our-code ...]
Caused by: javax.xml.bind.JAXBException: Implementation of JAXB-API has not been found on module path or classpath.
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:278) ~[jaxb-api-2.3.0.jar:2.3.0]
at javax.xml.bind.ContextFinder.find(ContextFinder.java:421) ~[jaxb-api-2.3.0.jar:2.3.0]
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:721) ~[jaxb-api-2.3.0.jar:2.3.0]
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:662) ~[jaxb-api-2.3.0.jar:2.3.0]
at [... our-code ...]
Caused by: …Run Code Online (Sandbox Code Playgroud) 我有一个使用Maven和Java的多模块项目.我现在正在尝试迁移到Java 9/10/11并实现模块(如JSR 376:Java平台模块系统,JPMS).由于项目已经由Maven模块组成,并且依赖项是直接的,因此为项目创建模块描述符非常简单.
每个Maven模块现在module-info.java在src/main/java文件夹中都有自己的模块描述符().测试类没有模块描述符.
但是,我偶然发现了一个我无法解决的问题,并没有找到任何关于如何解决的说明:
如何使用Maven和Java模块进行模块间测试依赖?
在我的例子中,我有一个"通用"Maven模块,它包含一些接口和/或抽象类(但没有具体的实现).在相同的Maven模块中,我有抽象测试来确保这些接口/抽象类的实现的正确行为.然后,有一个或多个子模块,接口/抽象类的实现和扩展抽象测试的测试.
但是,在尝试执行testMaven构建阶段时,子模块将失败并显示:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.0:testCompile (default-testCompile) on project my-impl-module: Compilation failure: Compilation failure:
[ERROR] C:\projects\com.example\my-module-test\my-impl-module\src\test\java\com\example\impl\FooImplTest.java:[4,25] error: cannot find symbol
[ERROR] symbol: class FooAbstractTest
[ERROR] location: package com.example.common
Run Code Online (Sandbox Code Playgroud)
我怀疑这是因为测试不是模块的一部分.即使Maven在模块范围内执行测试还有一些"魔力",但它不适用于我依赖的模块中的测试(出于某种原因).我该如何解决?
项目的结构如下所示(此处提供完整的演示项目文件):
????my-common-module
? ????pom.xml
? ????src
? ????main
? ? ????java
? ? ????com
? ? ? ????example
? ? ? ????common
? ? ? ????AbstractFoo.java (abstract, …Run Code Online (Sandbox Code Playgroud) java-9 ×10
java ×9
maven ×3
java-module ×2
azul-zulu ×1
java-10 ×1
java-platform-module-system ×1
jaxb ×1
junit ×1
lambda ×1
module ×1
module-info ×1
netty ×1
osgi ×1
pkcs#11 ×1
sunpkcs11 ×1
tomcat ×1
tycho ×1
version ×1
versioning ×1