使用Jaxb和JDK 9在applet中进行非法反射访问

AJP*_*rez 7 java applet jaxb java-9 java-module

我有一个Java applet,它提供了一个GUI来调用Web服务.它使用Jaxb来解析XML数据并将其解组为对象.它使用Java 1.5到1.8正确运行.使用Java 9,不是那么多.

我使用容器HTML在Internet Explorer 8 + JDK 9中启动它:

<applet code="com.blah.MyApplet" archive="myFatJarWithDependencies.jar" mayscript>
    <param name="cache_option" value="no" />
</applet>
Run Code Online (Sandbox Code Playgroud)

小程序加载很好,似乎工作; 但是,一旦我连接到Web服务,它那种停止工作.我把它缩小到这个代码片段(其中Foo是一个带有XML绑定注释的自动生成的类):

System.out.println("1");
JAXBContext jc = JAXBContext.newInstance(Foo.class);
System.out.println("2");
Run Code Online (Sandbox Code Playgroud)

Java的控制台显示1,然后......没有:它没有崩溃,applet仍然响应鼠标点击,它不会抛出任何异常......似乎根本没有错误.除了它没有对接收的数据做任何事情,它从不输出2.我已经尝试了替代JAXBContext.newInstance方法(使用包名,包名加上类加载器),但它们都是一样的.

如果我使用相同的JDK 9从Eclipse Oxygen运行项目,它确实有效.当我连接到Web服务时,它会输出一些警告,包括:

WARNING: Illegal reflective access by com.sun.xml.bind.v2.runtime.reflect.opt.Injector 
(file:/C:/.../.m2/repository/com/sun/xml/bind/jaxb-impl/2.0/jaxb-impl-2.0.jar) to method
java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int)

WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access
operations
Run Code Online (Sandbox Code Playgroud)

但随后它继续并加载数据(并输出2到控制台).我的猜测是同样的问题,即使Java控制台中没有显示警告.也许JDK默认--illegal-access=deny是从IE运行的时候?或者"默默地否认 - 所以 - 用户 - 不要发生什么线索" ......

有什么办法可以将--illegal-access=permit选项传递给JVM吗?(请记住,我不是直接调用JVM,我只有一个<applet>html标记)

有没有其他方法可以使它工作?也许在我的applet的清单文件中添加额外的东西?(顺便说一句,这看起来像这样):

Manifest-Version: 1.0
Build-Jdk: 1.8.0_144
Application-name: Blah
Permissions: all-permissions
Sealed: true

Name: blah/Blah.class
SHA-256-Digest: kpf244234234..ahjsdfksf=
...
Run Code Online (Sandbox Code Playgroud)

这些是我最初使用的Jaxb依赖项:

  • javax.xml.bind:jaxb-api:2.0
  • com.sun.xml.bind:jaxb-impl:2.0
  • com.sun.xml.bind:jaxb-xjc:2.0

我尝试将它们从v2.0更新到v2.3.0,它们应该与Java 9兼容:

  • javax.xml.bind:jaxb-api:2.3.0
  • com.sun.xml.bind:jaxb-impl:2.3.0
  • com.sun.xml.bind:jaxb-core:2.3.0
  • com.sun.xml.bind:jaxb-xjc:2.3.0

但问题仍然存在.在nullpointer的回答之后也试过这些,没有运气:

  • javax.xml.bind:jaxb-api:2.1
  • javax.xml:jaxb-impl:2.1
  • 删除了jaxb-xjc,显然它不需要......

Nam*_*man 2

也许 JDK 默认是--illegal-access=deny从 IE 运行的?

不是,JDK目前​​默认的模式是permitonly。

--illegal-access=permit打开运行时映像中每个模块中的每个包,以在所有未命名模块中进行编码,即,如果该包存在于 JDK 8 中,则在类路径上进行编码。这可以实现静态访问​​(即通过编译的字节码)和深度访问通过平台的各种反射 API 进行反射访问。

对任何此类包的第一次反射访问操作都会导致发出警告,但此后不会发出警告。此单个警告描述了如何启用进一步的警告。该警告无法被抑制。

该模式是 JDK 9 中的默认模式。它将在未来的版本中逐步淘汰并最终删除。


还有其他方法可以使其发挥作用吗?

对于使用,jaxb-api建议您遵循此答案,以确保您的模块使用javax.xml.bind:jaxb-api:2.3.0而不是com/sun/xml/bind/jaxb-impl/2.0/jaxb-impl-2.0.jar在日志中看到的。

您可以按照此处文档maven-compiler-plugin:3.7.0中的说明进行配置,以在不同的执行中将源代码从 1.5 编译到 JDK 8,并在交替执行中编译 JDK。