Поиск для частных классов - PullRequest
0 голосов
/ 26 января 2019

Я нахожусь в процессе перехода с Java 7 (yipes) на Java 11 для веб-приложения, но у меня возникают трудности при переносе некоторого кода из-за недопустимых отражающих предупреждений о доступе (это не мешает работе, но должнона самом деле они когда-либо реализуют свои угрозы для принудительного применения в будущем обновлении JDK, я хочу, чтобы мой код был готов).

Я пытаюсь вызвать методы реестра из класса WindowsPreferences (который является закрытым классом впакет java.util.prefs, поставляемый с JDK 11.0.2).

Ранее у меня был код, который инициализировал бы методы в конструкторе моего служебного класса, например:

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) на Method из частного класса, Я получаю

ПРЕДУПРЕЖДЕНИЕ: Произошла недопустимая операция отражающего доступа
ПРЕДУПРЕЖДЕНИЕ: незаконный отражающий доступ com.admin.utils.RegistryManager (file: // WebRoot / WEB-INF / classes /) методу java.util.prefs.WindowsPreferences.closeKey (long)
ПРЕДУПРЕЖДЕНИЕ: пожалуйста, рассмотрите возможность сообщить об этом сопровождающим com.admin.utils.RegistryManager
ПРЕДУПРЕЖДЕНИЕ: используйте --illegal-access = warn, чтобы включитьпредупреждения о дальнейших незаконных операциях доступа с отражением
ПРЕДУПРЕЖДЕНИЕ. Все будущие операции доступа будут запрещены в следующем выпуске

Затем я попытался использовать Lookup, чтобы получить MethodHandle s, используя unreflect, нопроблема сохраняется, поскольку класс является закрытым (это для другого метода, но это тот же базовый принцип):

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)

Что мне следует делать, чтобы правильно отразить закрытый класс (или это на самом деле то, что я не должен делать)

...