import java.lang.instrument.*;
import javassist.*;
import java.io.*;
import java.security.*;
public class InitializerLoggingAgent implements ClassFileTransformer {
public static void premain(String agentArgs, Instrumentation inst) {
inst.addTransformer(new InitializerLoggingAgent(), true);
}
private final ClassPool pool = new ClassPool(true);
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) {
try {
if (className.equals("java/lang/ExceptionInInitializerError")) {
CtClass klass = pool.makeClass(new ByteArrayInputStream(classfileBuffer));
CtConstructor[] ctors = klass.getConstructors();
for (int i = 0; i < ctors.length; i++) {
ctors[i].insertAfter("this.printStackTrace();");
}
return klass.toBytecode();
} else {
return null;
}
} catch (Throwable t) {
return null;
}
}
}
http://jboss-javassist.github.io/javassist/tutorial/tutorial.html
Download javassist zip from here http://jboss-javassist.github.io/javassist/ and explode it
Download Ant (Ant? yes, Ant!) from here https://ant.apache.org/bindownload.cgi
Build javassist source and put the javassist.jar file in the lib folder of your project, add it to build classpath.
Follow instructions to jar your JavaAgent with a MANIFEST.MF containing
Manifest-Version: 1.0 Premain-Class: InitializerLoggingAgent Can-Retransform-Classes: true
run java -javaagent:agentjar.jar MainClass
It works! Your Error is intercepted and stacktrace is printed! No more silently failing static initializers!
If you forget to add "Can-Retransform-Classes: true" in the MANIFEST.MF, you get the infamous "java.lang.UnsupportedOperationException: adding retransformable transformers is not supported in this environment"
No comments:
Post a Comment