Java9 JNLP --add - 打开不起作用

Ste*_*ke- 9 java jnlp java-web-start java-9 java-module

我创建了一个简单的测试用例来测试Java 9 Web Start的新模块.遗憾的是,Java 9 Web Start默认情况下不支持像常规Java 9那样的--permit-illegal-access.

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;
       }
   }
}
Run Code Online (Sandbox Code Playgroud)

这是我的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>
Run Code Online (Sandbox Code Playgroud)

这似乎与此处讨论的内容一致(如何将Java 9'--permit-illegal-access'标志传递给Webstart应用程序?).但是,它不起作用.在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 jdk.javaws@9/com.sun.javaws.Launcher.executeApplication(Launcher.java:1741)
    at jdk.javaws@9/com.sun.javaws.Launcher.executeMainClass(Launcher.java:1677)
    at jdk.javaws@9/com.sun.javaws.Launcher.doLaunchApp(Launcher.java:1525)
    at jdk.javaws@9/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 jdk.javaws@9/com.sun.javaws.Launcher.executeApplication(Launcher.java:1741)
    at jdk.javaws@9/com.sun.javaws.Launcher.executeMainClass(Launcher.java:1677)
    at jdk.javaws@9/com.sun.javaws.Launcher.doLaunchApp(Launcher.java:1525)
    at jdk.javaws@9/com.sun.javaws.Launcher.run(Launcher.java:158)
    at java.base/java.lang.Thread.run(Thread.java:844)
Run Code Online (Sandbox Code Playgroud)

我不清楚我的错误在哪里以及为什么java.awt.Toolkit无法通过Reflection使用.

Ste*_*ke- 10

因为Java 9不够混淆,正确的答案是:

<j2se version="9" java-vm-args="--add-opens=java.desktop/java.awt=ALL-UNNAMED"  />
Run Code Online (Sandbox Code Playgroud)

这等于符号在JNLP文件中很重要,但不在命令行上!

在命令行上这两个:

java --illegal-access=deny --add-opens java.desktop/java.awt=ALL-UNNAMED -cp . Java9BreaksWhenTest
Run Code Online (Sandbox Code Playgroud)

java --illegal-access=deny --add-opens=java.desktop/java.awt=ALL-UNNAMED -cp . Java9BreaksWhenTest
Run Code Online (Sandbox Code Playgroud)

工作正常!

  • 是的,javac和java命令行工具允许您将选项和值与空格分开(当然也可以使用'=').JNI调用API和配置文件(包括JNLP)必须始终使用'='来分隔名称和值.关于这个主题的一些背景知识可以在JEP 293(http://openjdk.java.net/jeps/293)中找到. (5认同)