Мне нужно изменить значение закрытой переменной в классе частного пакета из класса внешнего пакета.
- package: java.util.jar из jdk-9.0.1
- класс: JarVerifier.java
- переменная: parsingBlockOrSF (private boolean)
Я пробовал это:
private void writePrivateJarVerifierField(boolean newValue) throws Exception {
Class<?> clazz = Class.forName("java.util.jar.JarVerifier");
Field field = clazz.getDeclaredField("parsingBlockOrSF");
field.setAccessible(true);
field.setBoolean(clazz.newInstance(), newValue);
}
Это дает мне Exception in thread "main" java.lang.InstantiationException: java.util.jar.JarVerifier
Я видел этот , этот , этот и этот вопрос уже, хотя я не могу получитьрешение моей проблемы.
Может кто-нибудь дать мне подсказку, пожалуйста?
Изменить 1: , так как я хочу изменить значение parsingBlockOrSF во время выполнения (как будто я изменил его через отладчик) Мне нужен существующий экземпляр JarVerifier, то есть JarFile (спасибо Gyro Gearless) Взглянув на подход, предложенный Ankur Chrungoo, я понял, что мне нужно получить уже существующий экземпляр JarVerifierтаким образом я попробовал это:
private void writePrivateJarVerifierField(boolean newValue, JarFile jf) throws Exception {
Class<?> clazz = Class.forName("java.util.jar.JarVerifier");
Class<?> clacc = Class.forName("java.util.jar.JarFile");
Field field = clazz.getDeclaredField("parsingBlockOrSF");
Field field1 = clacc.getDeclaredField("jv");
field.setAccessible(true);
field1.setAccessible(true);
field.setBoolean(field1.get(jf), newValue);
}
Где JarFile jf создает новый экземплярe JarVerifier и сохраняет его в переменной с именем jv.Вот почему я намереваюсь получить оба класса JarVerifier и JarFile, чтобы получить обе переменные, к которым я хочу получить доступ (одна из них является действительным логическим значением parsingBlockOrSF из JarVerifier, а другая - из экземпляра JarVerifier jv из экземпляра JarFile. На мой взгляд,приведенный выше код имеет смысл и должен работать, но это не так, так в чем же моя ошибка?
Исключение, которое я получаю: java.lang.NullPointerException at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:57)
Редактировать 2: изменив последнюю строку кода выше на: field.setBoolean(field1.getType(), newValue);
Кажется, что объект распознан, хотя он Can not set boolean field java.util.jar.JarVerifier.parsingBlockOrSF to java.lang.Class
Редактировать 3: используя этот код:
Class<?> clazz = Class.forName("java.util.jar.JarVerifier");
Class<?> clacc = Class.forName("java.util.jar.JarFile");
Field field = clazz.getDeclaredField("parsingBlockOrSF");
Field field1 = clacc.getDeclaredField("jv");
field.setAccessible(true);
field1.setAccessible(true);
field.setBoolean(clazz.getConstructor(byte[].class).newInstance(new byte[1]), newValue);
Я получаю эту ошибку: Exception in thread "main" java.lang.IllegalAccessException: class JarVerifier cannot access a member of class java.util.jar.JarVerifier (in module java.base) with modifiers "public"
Здесь я хочу изменить значение parsingBlockOrSF в jarVerifier внутри JarFile, поэтому ясначала должен работать с экземпляром jarFile, извлечь из него jarVerifier (что я пытаюсь сделать с field1 = calcc.getDeclaredField ("jv"), так как jarVerifier хранится в переменной jv внутри JarFile), а затем с помощью этогооbject, измените его свойство
Код, в котором создается JarFile:
JarFile jf = null;
jf = new JarFile(jarName, true);
jarName - это строка, представляющая путь к файлу .jar