8

我有一个 Java 小程序,它提供了一个 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>

小程序加载正常并且似乎可以工作;但是,一旦我连接到 Web 服务,它就会停止工作。我已将其缩小到此代码片段(其中Foo是带有 XML 绑定注释的自动生成的类):

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

Java 的控制台显示1,然后......什么都没有:它不会崩溃,小程序仍然响应鼠标点击,它不会抛出任何异常......似乎根本没有错误。除了它不对接收到的数据做任何事情,而且它从不输出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

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

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

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

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 依赖项:

  • 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,显然不需要...
4

1 回答 1

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。

于 2017-09-28T16:52:41.957 回答