Это можно сделать с помощью агентов Java и инструментальной библиотеки.
Агент Java — отдельный код, который можно запустить перед основной частью кода.
Инструментарий — изменение исходного кода во время загрузки программы.
Код для работы
(взято из appcrawler и немного изменен):
Исходный код agent.jar:
Простой трансформер.java:
package test;
import java.security.*;
import java.lang.instrument.*;
import java.util.*;
import javassist.*;
public class SimpleTransformer implements ClassFileTransformer {
public SimpleTransformer() {
super();
}
public byte[] transform(ClassLoader loader, String className, Class redefiningClass, ProtectionDomain domain, byte[] bytes) throws IllegalClassFormatException {
return transformClass(redefiningClass,bytes);
}
private byte[] transformClass(Class classToTransform, byte[] b) {
ClassPool pool = ClassPool.getDefault();
CtClass cl = null;
try {
cl = pool.makeClass(new java.io.ByteArrayInputStream(b));
CtBehavior[] methods = cl.getDeclaredBehaviors();
for (int i = 0; i < methods.length; i++) {
if (methods[i].isEmpty() == false) {
changeMethod(methods[i]);
}
}
b = cl.toBytecode();
}
catch (Exception e) {
e.printStackTrace();
}
catch (Throwable t) {
t.printStackTrace();
}
finally {
if (cl != null) {
cl.detach();
}
}
return b;
}
private void changeMethod(CtBehavior method) throws NotFoundException, CannotCompileException {
/*if (method.getName().equals("doIt")) {
method.insertBefore("System.out.println(\"started method at \" + new java.util.Date());");
method.insertAfter("System.out.println(\"ended method at \" + new java.util.Date());");
}*/
//MY CODE
//!Modifier.isAbstract(method.getModifiers()) -- abstract methods can't be modified. If you get exceptions, then add this to the if statement.
//native methods can't be modified.
if (!Modifier.isNative(method.getModifiers())) {
String insertString = "System.out.println(\"started method " + method.getName() + "\");";
method.insertBefore(insertString);
}
}
SimpleMain.java:
package test;
import java.lang.instrument.Instrumentation;
public class SimpleMain {
public static void premain(String agentArguments, Instrumentation instrumentation) {
instrumentation.addTransformer(new SimpleTransformer());
}
}
МАНИФЕСТ.mf:
Manifest-Version: 1.0
Boot-Class-Path: javassist.jar
Premain-Class: test.SimpleMain
Возьмите эти файлы и упакуйте их в файл jar. Также не забудьте включить файлы из javassist.jar (можно загрузить с www.javassist.org) и tools.jar. (находится в Program Files/Java/jdk/lib/). Не уверен, что второй нужен, но в статье написано, что он почему-то нужен.
Теперь вы можете использовать этот jar-файл в качестве java-агента.
java -javaagent:agent.jar YourJavaProgram
И вуаля. Агент Java будет обрабатывать все методы и распечатывать каждый метод, вызванный во время выполнения.
person
Nopslide
schedule
26.03.2017