2

我正在为 Web 应用程序从 Java 7 (yipes) 迁移到 Java 11,但由于非法反射访问警告而在迁移某些代码时遇到了困难(它不会阻止事情的工作,但他们是否真的应该在未来的 JDK 更新中执行他们的威胁,我希望我的代码准备好)。

我正在尝试从 WindowsPreferences 类(这是 11.0.2 JDK 附带的 java.util.prefs 包中的私有类)调用注册表方法。

我以前有代码可以在我的实用程序类的构造函数中初始化方法,如下所示:

private static Preferences userRoot = Preferences.userRoot();
private static Class<? extends Preferences> userClass = userRoot.getClass();    
private static Method regOpenKey = null;

...

static {
  try {
    regOpenKey = userClass.getDeclaredMethod("WindowsRegOpenKey", new Class[] {int.class, byte[].class, int.class});
    regOpenKey.setAccessible(true);
...
  }
}

然后我可以稍后像这样调用它们:

int[] handles = (int[]) regOpenKey.invoke(preferences, new Object[] {
            new Integer(hive), toCstr(keyName), new Integer(KEY_READ | wow64) });

这对于 Java 7 非常有效,但在 Java 11 中我不得不重新调整一些东西。

我现在拥有的是:

private static Preferences userRoot = Preferences.userRoot();
private static Class<? extends Preferences> userClass = userRoot.getClass();    
private static Method regOpenKey = null;

...

static {
  try {
    userRegOpenKey = userClass.getDeclaredMethod("openKey", byte[].class, int.class, int.class);
    userRegOpenKey.setAccessible(true);
...
  }
}

long handle = (long) userRegOpenKey.invoke(preferences, toCstr(keyName), hive, wow64));

这工作得很好,我可以很好地从注册表中读取,但是每当我从私人课程中调用.setAccessible(true)a时,我都会得到Method

警告:发生非法反射访问操作
警告:com.admin.utils.RegistryManager (file://WebRoot/WEB-INF/classes/) 对方法 java.util.prefs.WindowsPreferences.closeKey(long)的非法反射访问
警告:请考虑将此报告给 com.admin.utils.RegistryManager 的维护者
警告:使用 --illegal-access=warn 启用对进一步非法反射访问操作的
警告 警告:所有非法访问操作将在未来版本中被拒绝

然后我尝试使用Lookup来获取MethodHandles usingunreflect但问题仍然存在,因为该类是私有的(这是针对不同的方法,但基本原理相同):

Lookup lookup = MethodHandles.lookup();

Method systemRegCloseKeyDeclaredMethod = systemClass.getDeclaredMethod("closeKey", long.class);
systemRegCloseKeyDeclaredMethod.setAccessible(true);

systemRegCloseKey = lookup.unreflect(systemRegCloseKeyDeclaredMethod);

我仍然收到警告,systemRegCloseKeyDeclaredMethod.setAccessible(true);但如果我将其注释掉,则会出现运行时异常:

java.lang.IllegalAccessException:类不公开:java.util.prefs.WindowsPreferences.closeKey[Ljava.lang.Object;@4c6e276e/invokeVirtual,来自 com.admin.utils.RegistryManager(未命名模块 @6ee52dcd)

我应该怎么做才能正确反映私人课程(或者这实际上是我不应该做的事情)?

4

0 回答 0