首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java9WebStart JNLP服务生成IllegalAccess

Java9WebStart JNLP服务生成IllegalAccess
EN

Stack Overflow用户
提问于 2017-10-10 14:13:18
回答 1查看 367关注 0票数 2

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

代码语言:javascript
复制
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

结果在

代码语言:javascript
复制
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

怎么解决这个问题呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-10-10 14:13:18

正如前面更一般的question中所讨论的那样,问题是第二个反射方法不是由公共API类定义的,而是由私有实现定义的,这是因为Java9可访问性规则适用了。

修复方法是将getCodeBase方法基于公共接口,而不是:

代码语言:javascript
复制
Class<?> sclass = Class.forName("javax.jnlp.BasicService");

这也避免了使用动态定义类的反射反模式。

使用静态实现也可以避免这个问题(然而,这存在需要javaws.jar的问题,这在某些构建环境中可能不容易获得)。

代码语言:javascript
复制
import javax.jnlp.BasicService;
import javax.jnlp.ServiceManager;

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

感谢https://stackoverflow.com/users/2711488/holger检查反射实现和https://stackoverflow.com/users/7463126/alan-bateman,在没有看到代码的情况下猜测实际问题是什么。按照https://stackoverflow.com/users/2525313/nicolai的建议,将这两个问题分开,使其更加清晰。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46669000

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档