Java 9 Webstart JNLP服务产生IllegalAccess [英] Java 9 webstart JNLP Service produces IllegalAccess

查看:129
本文介绍了Java 9 Webstart JNLP服务产生IllegalAccess的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码(通过JNLP API检索Java Web Start客户端应用程序的基本URL)在Java 8中有效,但在(模块化)Java 9运行时中执行失败:

The following code (to retrieve the base URL of a Java Web Start client application via the JNLP API) worked in Java 8 but failed when executed in (modularized) Java 9 runtime:

Class<?> mclass = Class.forName("javax.jnlp.ServiceManager");
Method lookup = mclass.getMethod("lookup", new Class[]{String.class});
Object basicSvc = lookup.invoke(null, new Object[{"javax.jnlp.BasicService"});
Class<?> sclass = basicSvc.getClass();
Method getCodeBase = sclass.getMethod("getCodeBase", (Class[])null);
URL codebase = (URL)getCodeBase.invoke(basicSvc, (Object[])null); // throws

结果

java.lang.IllegalAccessException: class app.App cannot access class
  com.sun.jnlp.BasicServiceImpl (in module jdk.javaws) because module
  jdk.javaws does not export com.sun.jnlp to unnamed module @7202a0fa
    at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException
    at java.base/java.lang.reflect.AccessibleObject.checkAccess
    at java.base/java.lang.reflect.Method.invoke
    at app.App.init

如何解决?

推荐答案

如先前更常见的

As discussed in a previous more general question the problem is that the second reflection method is not defined by the public API class but the private implementation, which does not work since Java 9 accesibility rules apply.

解决方法是将getCodeBase方法基于公共接口:

The fix is to base the getCodeBase method against the public interface instead:

Class<?> sclass = Class.forName("javax.jnlp.BasicService");

这也避免了反射反模式与动态定义类一起使用.

This also avoids the reflection anti-pattern to work with dynamic defining classes.

使用静态实现也可以避免该问题(但是存在一个问题,即它需要javaws.jar,在某些构建环境中可能不容易获得).

Using a static implementation would also avoid the problem (however this has the problem that it requires the javaws.jar which might not be easy to obtain in some build environments).

import javax.jnlp.BasicService;
import javax.jnlp.ServiceManager;

BasicService basicSvc = (BasicService)ServiceManager.lookup("javax.jnlp.BasicService");
URL u = basicSvc.getCodeBase();


感谢 @Holger 检查反射实现和 @nicolai 的建议,将这两个问题分开了,这使它更加简洁.


Thanks to @Holger to check the reflection implementation and @Alan Bateman in guessing what the actual problem was without seeing the code. Seperated the two questions as suggested by @nicolai, which makes it much cleaner.

这篇关于Java 9 Webstart JNLP服务产生IllegalAccess的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆