Java9 JNLP - 添加 - 打开不起作用
问题描述:
我创建了一个简单的测试用例来测试Java 9 Web Start的新模块。不幸的是,Java 9 Web Start默认不支持像普通Java 9那样的--permit-illegal-access。Java9 JNLP - 添加 - 打开不起作用
Java 9 Web Start假定支持--add-opens(请参阅https://bugs.openjdk.java.net/browse/JDK-8172986)。
我正在使用Java 1.9.0_181_ea。
这里是我的测试类:
import java.awt.Toolkit;
import java.lang.reflect.Method;
import java.lang.IllegalAccessException;
import java.lang.reflect.InvocationTargetException;
public class Java9BreaksWhenTest {
public static void main(String args[]) throws IllegalAccessException, InvocationTargetException {
System.out.println("Hello World");
// Do some dangerous reflection
Toolkit toolkit = Toolkit.getDefaultToolkit();
Class c = toolkit.getClass();
while(true) {
Method m = null;
try {
m = c.getDeclaredMethod("setDesktopProperty", String.class, Object.class);
} catch (NoSuchMethodException ex) {
c = c.getSuperclass();
if (c!=null)
continue;
} catch (SecurityException ex) {
ex.printStackTrace();
}
if (m!=null) {
m.setAccessible(true);
m.invoke(toolkit, "awt.font.desktophints", null);
System.out.println("desktop Properties changed.");
}
break;
}
}
}
这里是我的JNLP文件中,应使java.awt中的代码能够访问。
<?xml version="1.0" encoding="UTF-8"?>
<jnlp spec="1.0+" codebase="file:///home/smm/hcs/testcode" href="java9BreaksWhenTest.jnlp">
<information>
<title>Java 9 Breaks When Test</title>
<vendor>HCS</vendor>
<homepage href="http://hcs.us.com"/>
<description>Java 9 Breaks When Test</description>
<description kind="short">Java 9 Breaks When Test</description>
</information>
<security><all-permissions/></security>
<update check="timeout" policy="always"/>
<resources>
<j2se version="9" java-vm-args="--add-opens java.desktop/java.awt=ALL-UNNAMED" />
<jar href="Java9BreaksWhenTest.jar" main="true" download="eager"/>
</resources>
<application-desc main-class="Java9BreaksWhenTest">
</application-desc>
</jnlp>
这似乎与这里讨论的内容(How to pass the Java 9 '--permit-illegal-access' flag to a Webstart application?)内联。但是,它不起作用。在Java Web Start的运行它,我得到以下错误:
Hello World
java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at [email protected]/com.sun.javaws.Launcher.executeApplication(Launcher.java:1741)
at [email protected]/com.sun.javaws.Launcher.executeMainClass(Launcher.java:1677)
at [email protected]/com.sun.javaws.Launcher.doLaunchApp(Launcher.java:1525)
at [email protected]/com.sun.javaws.Launcher.run(Launcher.java:158)
at java.base/java.lang.Thread.run(Thread.java:844)
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make protected final void java.awt.Toolkit.setDesktopProperty(java.lang.String,java.lang.Object) accessible: module java.desktop does not "opens java.awt" to unnamed module @1f749ac
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:337)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:281)
at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:198)
at java.base/java.lang.reflect.Method.setAccessible(Method.java:192)
at Java9BreaksWhenTest.main(Java9BreaksWhenTest.java:26)
... 9 more
#### Java Web Start Error:
#### Unable to make protected final void java.awt.Toolkit.setDesktopProperty(java.lang.String,java.lang.Object) accessible: module java.desktop does not "opens java.awt" to unnamed module @1f749ac
java.lang.reflect.InaccessibleObjectException: Unable to make protected final void java.awt.Toolkit.setDesktopProperty(java.lang.String,java.lang.Object) accessible: module java.desktop does not "opens java.awt" to unnamed module @1f749ac
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:337)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:281)
at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:198)
at java.base/java.lang.reflect.Method.setAccessible(Method.java:192)
at Java9BreaksWhenTest.main(Java9BreaksWhenTest.java:26)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at [email protected]/com.sun.javaws.Launcher.executeApplication(Launcher.java:1741)
at [email protected]/com.sun.javaws.Launcher.executeMainClass(Launcher.java:1677)
at [email protected]/com.sun.javaws.Launcher.doLaunchApp(Launcher.java:1525)
at [email protected]/com.sun.javaws.Launcher.run(Launcher.java:158)
at java.base/java.lang.Thread.run(Thread.java:844)
目前还不清楚我在哪里我的错误是,为什么java.awt.Toolkit中的不可用通过反射使用。
答
由于Java 9不够混淆,正确的答案是:
<j2se version="9" java-vm-args="--add-opens=java.desktop/java.awt=ALL-UNNAMED" />
这等号在JNLP文件的问题,但确实没有在命令行上!
在命令行上都这样:
java --illegal-access=deny --add-opens java.desktop/java.awt=ALL-UNNAMED -cp . Java9BreaksWhenTest
和
java --illegal-access=deny --add-opens=java.desktop/java.awt=ALL-UNNAMED -cp . Java9BreaksWhenTest
正确
工作!
对,javac和java命令行工具允许用空格分隔选项和值(当然也可以使用'=')。 JNI调用API和配置文件(包括JNLP)必须始终使用'='来分隔名称和值。关于这个主题的一些背景可以在JEP 293中找到(http://openjdk.java.net/jeps/293)。 –