Java Instrumentation ClassFileTransformer с генерируемыми классами JDK DelgatingClassLoaderJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Java Instrumentation ClassFileTransformer с генерируемыми классами JDK DelgatingClassLoader

Сообщение Anonymous »

В настоящее время я работаю над агентом Java, который изменяет байт -код классов, добавляя маркер.
Цель состоит в том, чтобы инструмент только для классов из моего проекта, но для целей тестирования я временно настроил агент для инструментов все пакеты, включая классы, нагрузки на jdk. < /p>
. До выполнения агента Java.

Код: Выделить всё

jdk.internal.reflect.MethodAccessorGenerator
< /code>
Этот класс динамически генерирует другой класс через: < /p>
return JLA.defineClass(newLoader, name, bytes, null, "__ClassDefiner__");
< /code>
Этот код запускает преобразование класса класса, даже для динамически сгенерированных классов.
i заключаю, что если это разрешено без ограничения на собственном уровне JVM, то это должно быть возможно для прибора этих сгенерированных классов.package jdk.internal.reflect;

import java.lang.reflect.InvocationTargetException;
import java.rmi.server.RemoteObject;

public class GeneratedSerializationConstructorAccessor1 extends SerializationConstructorAccessorImpl {

public Object newInstance(Object[] var1) throws InvocationTargetException {
RemoteObject var10000;
RemoteObject var10001;
try {
var10000 = new RemoteObject;
var10001 = var10000;
if (var1 != null && var1.length != 0) {
throw new IllegalArgumentException();
}
} catch (NullPointerException | ClassCastException var3) {
throw new IllegalArgumentException(var3.toString());
}

try {
var10001.();
return var10000;
} catch (Throwable var2) {
throw new InvocationTargetException(var2);
}
}
}
Успешная инструментация [/b]
Когда я инструментарует этот класс с простой линией трассировки, он работает отлично:

Код: Выделить всё

package jdk.internal.reflect;

import fr.code.api.CodeMonitoring;
import java.lang.reflect.InvocationTargetException;
import java.rmi.server.RemoteObject;

public class GeneratedSerializationConstructorAccessor1 extends SerializationConstructorAccessorImpl {
private static boolean b_code_newInstance_0;

public Object newInstance(Object[] var1) throws InvocationTargetException {
CodeMonitoring.callMethod("jdk/internal/reflect/GeneratedSerializationConstructorAccessor1", "newInstance", "([Ljava/lang/Object;)Ljava/lang/Object;");

RemoteObject var10000;
RemoteObject var10001;
try {
var10000 = new RemoteObject;
var10001 = var10000;
if (var1 != null && var1.length != 0) {
throw new IllegalArgumentException();
}
} catch (NullPointerException | ClassCastException var3) {
throw new IllegalArgumentException(var3.toString());
}

try {
var10001.();
return var10000;
} catch (Throwable var2) {
throw new InvocationTargetException(var2);
}
}
}
неудачная инструментация
Однако, если я назначу результат вызова метода логической переменной, JVM сбои:

Код: Выделить всё

b_code_newInstance_0 = CodeMonitoring.callMethod("jdk/internal/reflect/GeneratedSerializationConstructorAccessor1", "newInstance", "([Ljava/lang/Object;)Ljava/lang/Object;");
< /code>
[b] наблюдаемая проблема < /strong> < /p>
В Java 8 это запускает исключение:
Java.lang.noclassDeffounderRorrish> Вопрос < /strong> < /p>
Я понимаю, что этот класс является внутренним, динамически сгенерированным классом в Java.
Поскольку его можно инструментально, мне просто любопытно понять, почему присвоение результата логическому выбору, в то время как простой метод не делает. Примечание [/b] 
Сгенерированный код, будь то в Java 8 или Java 21, имеет основную версию Bytecode 49, которая соответствует Java 5. 
Код ASM, используемый для изменения этого байткода, следующим: 
  public void visitCode() {
super.visitCode();

mv.visitLdcInsn(className);
mv.visitLdcInsn(name);
mv.visitLdcInsn(descriptor);
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "fr/deadcode/api/CodeMonitoring", "callMethod", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z", false);
mv.visitFieldInsn(Opcodes.PUTSTATIC, className, field, "Z");
}
Спасибо, ребята,

Подробнее здесь: https://stackoverflow.com/questions/797 ... elegatingc
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»