问题
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.
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>
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'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.
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
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"...
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=
...
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
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-core : 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
- removed the jaxb-xjc, apparently it's not needed...
回答1:
Maybe the JDK defaults to --illegal-access=deny
when it's being run from IE?
No, the current default mode of JDK is permit
only.
--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.
This mode is the default in JDK 9. It will be phased out in a future release and, eventually, removed.
Is there any other way to make it work?
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.
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.
来源:https://stackoverflow.com/questions/46474104/illegal-reflective-access-in-an-applet-with-jaxb-and-jdk-9