首页 > 解决方案 > 对 StartUpWMClassName 的工具包反射访问警告

问题描述

我正在创建一个 IDE(它的开源,看看),

主窗口

所以为了改变StartUpWMClassNameLinux上的,

我用过这段代码:

Toolkit toolkit = Toolkit.getDefaultToolkit();
java.lang.reflect.Field field = toolkit.getClass().getDeclaredField("awtAppClassName");
field.setAccessible(true);
field.set(toolkit, "Omega IDE");

这会在运行时生成此警告:

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by ide.Screen (file:/usr/bin/Omega%20IDE.jar) to field sun.awt.X11.XToolkit.awtAppClassName
WARNING: Please consider reporting this to the maintainers of ide.Screen
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

有没有其他方法可以在没有任何警告且不使用System.setProperty("--illegal-access", "permit")) 的情况下做同样的事情?

标签: javalinuxreflectionwarnings

解决方案


错误报告JDK-6528430仍处于打开状态。换句话说,仍然没有官方的 API 来控制这个特性。

AWT 中提到了我能找到的最接近的Taskbar

Linux 支持目前仅限于 Unity。但是,要使这些功能在 Unity 上运行,应用程序应从 .desktop 文件运行,并将指定的java.desktop.appName系统属性设置为此 .desktop 文件名:Exec=java -Djava.desktop.appName=MyApp.desktop -jar /path/to/myapp.jar

此系统属性java.desktop.appName仅影响实现控制下的功能Taskbar,而不影响整个 AWT Toolkit

因此,如果这还不够,您必须忍受反射访问的缺点。但是你必须知道这只能是一个临时的解决方案,因为未来的版本对反射访问的限制会更加严格,而且,这个字段根本不能保证存在。

这个答案包含一个解决方法,以消除警告。您只需要将其调整到您的类和目标包。

Module mod = ide.Screen.class.getClassLoader().getUnnamedModule();
if(mod == ide.Screen.class.getModule()) {
    Toolkit.getDefaultToolkit().getClass().getModule().addOpens("sun.awt.X11", mod);
}

该答案中提到的限制也适用于您的案例。这个技巧只适用于未命名的模块,换句话说,通过类路径加载的代码。真实模块需要在启动时指定配置,以打开包进行反射访问。如上所述,未来的 Java 版本可能会限制更多并关闭这扇门。让我们希望链接的错误在此之前得到解决,这样就可以切换到官方 API。


推荐阅读