2017-08-30 108 views
5

我創建了一個簡單的測試用例來測試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中的不可用通過反射使用。

回答

6

由於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 
正確

工作!

+4

對,javac和java命令行工具允許用空格分隔選項和值(當然也可以使用'=')。 JNI調用API和配置文件(包括JNLP)必須始終使用'='來分隔名稱和值。關於這個主題的一些背景可以在JEP 293中找到(http://openjdk.java.net/jeps/293)。 –