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