工具包对 StartUpWMClassName 的反射访问警告

Toolkit Reflective access warning to StartUpWMClassName

我正在创建一个 IDE(它是开源的,have a look),

所以为了在 Linux、

上更改 StartUpWMClassName

我用过这个代码:

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")) 的情况下执行相同操作?

有一个错误报告 JDK-6528430 仍然开放。也就是说,目前还没有官方API来控制这个功能。

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

Linux support is currently limited to Unity. However to make these features work on Unity, the app should be run from a .desktop file with specified java.desktop.appName system property set to this .desktop file name: Exec=java -Djava.desktop.appName=MyApp.desktop -jar /path/to/myapp.jar

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

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

包含一个解决方法,用于消除警告。您只需根据您的 class 和目标包对其进行调整。

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

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