使用 Jaxb 和 JDK 9 的小程序中的非法反射访问 [英] Illegal reflective access in an applet with Jaxb and JDK 9

查看:43
本文介绍了使用 Jaxb 和 JDK 9 的小程序中的非法反射访问的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 Java 小程序,它提供了一个 GUI 来调用 Web 服务.它使用 Jaxb 解析 XML 数据并将其解组为对象.它可以在 Java 1.5 到 1.8 中正确运行.使用 Java 9,就没有那么多了.

I have a Java applet which provides a GUI to invoke a web service. It uses Jaxb to parse the XML data and unmarshall it into objects. It runs correctly with Java 1.5 to 1.8. With Java 9, not so much.

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

I use a container HTML to launch it in Internet Explorer 8 + JDK 9:

<applet code="com.blah.MyApplet" archive="myFatJarWithDependencies.jar" mayscript>
    <param name="cache_option" value="no" />
</applet>

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

The applet loads fine and seems to work; however, once I connect to the web service, it kind of stops working. I have narrowed it down to this code fragment (where Foo is an auto-generated class with XML bind annotations):

System.out.println("1");
JAXBContext jc = JAXBContext.newInstance(Foo.class);
System.out.println("2");

Java 的控制台显示 1,然后……什么都没有:它没有崩溃,小程序仍然响应鼠标点击,它没有抛出任何异常……似乎有完全没有错误.除了它不对接收到的数据做任何事情之外,它从不输出2.我尝试过其他 JAXBContext.newInstance 方法(带有包名、包名和类加载器),但它们都是一样的.

Java's console shows the 1, and then... nothing: it doesn't crash, the applet is still responsive to mouse clicks, it doesn't throw any exceptions... there seems to be no error at all. Except for the fact that it doesn't do anything with the received data, and it never outputs the 2. I've tried alternative JAXBContext.newInstance methods (with a package name, with a package name plus a class loader), but they all do the same.

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

If I run the project from Eclipse Oxygen with the same JDK 9, it does work. When I connect to the web service, it outputs a few warnings, including these:

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

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

But then it goes on and loads the data (and outputs the 2 to the console). My guess is it's the same problem, even if the warnings are not shown in the Java console. Maybe the JDK defaults to --illegal-access=deny when it's being run from IE? Or "silently-deny-so-the-user-dont-have-a-clue-on-whats-happening"...

有什么方法可以将 --illegal-access=permit 选项传递给 JVM?(请记住,我没有直接调用JVM,我只有一个 html 标签)

Is there any way in which I can pass the --illegal-access=permit option to the JVM? (Keep in mind that I'm not directly invoking the JVM, I only have an <applet> html tag)

还有其他方法可以让它工作吗?也许在我的小程序的清单文件中添加一些额外的东西?(顺便说一下,看起来像这样):

Is there any other way to make it work? Perhaps add something extra in my applet's manifest file? (Which, by the way, looks like this):

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

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

These are the Jaxb dependencies I was using originally:

  • 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 兼容:

I tried updating them from v2.0 to v2.3.0, which are supposed to be compatible with Java 9:

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

但问题依然存在.在空指针的回答之后也尝试过这些,但也没有运气:

But the problem still persists. Also tried these after nullpointer's answer, with no luck either:

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

推荐答案

也许 JDK 在从 IE 运行时默认为 --illegal-access=deny?

不,JDK当前默认模式是permit only.

No, the current default mode of JDK is permit only.

--illegal-access=permit 打开每个模块中的每个包运行时映像在所有未命名模块中编码,即在类路径,如果该包存在于 JDK 8 中.这将启用静态访问,即通过编译的字节码和深度反射访问,通过平台的各种反射 API.

--illegal-access=permit opens each package in each module in the run-time image to code in all unnamed modules, i.e., to code on the class path, if that package existed in JDK 8. This enables both static access, i.e., by compiled bytecode, and deep reflective access, via the platform's various reflection APIs.

对任何此类包的第一次反射访问操作会导致发出警告,但在那之后不会发出警告.此单个警告描述了如何启用更多警告.这个警告无法抑制.

The first reflective-access operation to any such package causes a warning to be issued, but no warnings are issued after that point. This single warning describes how to enable further warnings. This warning cannot be suppressed.

此模式是 JDK 9 中的默认模式.以后会被淘汰发布并最终删除.

This mode is the default in JDK 9. It will be phased out in a future release and, eventually, removed.

<小时>

还有其他方法可以让它工作吗?

对于使用 jaxb-api 建议您遵循 这个答案 以确保您的模块使用 javax.xml.bind:jaxb-api:2.3.0 而不是 com/sun/xml/bind/jaxb-impl/2.0/jaxb-impl-2.0.jar 如您的日志中所见.

For using the jaxb-api would suggest you follow this answer to make sure that your module uses the javax.xml.bind:jaxb-api:2.3.0 instead of com/sun/xml/bind/jaxb-impl/2.0/jaxb-impl-2.0.jar as seen in your logs.

您可以按照此处的文档 将源代码从 1.5 编译到不同执行的 JDK 8 和交替执行的 JDK.

You can configure the maven-compiler-plugin:3.7.0 as stated in the documentation here to compile sources from 1.5 to JDK 8 in different execution and JDK in alternate execution.

这篇关于使用 Jaxb 和 JDK 9 的小程序中的非法反射访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆