Есть javaagent со следующим ClassFileTransformer:
import java.lang.instrument.Instrumentation;
public class Premain {
public static void premain(String agentArgument, Instrumentation instrumentation) {
instrumentation.addTransformer(new ClassTransformer());
}
}
и
import javassist.*;
import java.io.IOException;
import java.lang.instrument.ClassFileTransformer;
import java.security.ProtectionDomain;
public class ClassTransformer implements ClassFileTransformer {
private final String JBUTTON_CLASS_NAME = "javax/swing/JButton";
private final String NEW_CONSTRUCTOR_CODE = "{ this(null, null); System.out.println(\"Good\"); }";
@Override
public byte[] transform(ClassLoader loader,
String className,
Class<?> classBeingRedefined,
ProtectionDomain protectionDomain,
byte[] classfileBuffer) {
if (JBUTTON_CLASS_NAME.equals(className)) {
System.out.println(0);
ClassPool classPool = ClassPool.getDefault();
System.out.println(1);
try {
System.out.println(2);
CtClass ctClass = classPool.get(JBUTTON_CLASS_NAME);
System.out.println(3);
CtConstructor declaredConstructor = ctClass.getDeclaredConstructor(null);
System.out.println(4);
declaredConstructor.setBody(NEW_CONSTRUCTOR_CODE);
System.out.println(5);
return ctClass.toBytecode();
} catch (IOException | NotFoundException | CannotCompileException ex) {
System.out.println(6);
ex.printStackTrace();
}
}
return classfileBuffer;
}
}
Запуская его применительно к такому swing приложения:
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Main {
public static void main(String[] args) {
JButton button = new JButton();
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("Click button");
}
});
JFrame jFrame = new JFrame("Agent tester");
jFrame.getContentPane().add(button);
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jFrame.setSize(300, 300);
jFrame.setVisible(true);
}
}
В итоге в консоль выводится следующие:
0
1
2
3
И все. Все тормозится на первом обращении к ctClass. Вообще любая операция с ним обрывает вывод, если прописать System.out.println(ctClass); получим тоже самое.
Из за чего это происходит и как это исправить?
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости