Java中是否有一种方法可以通过使用Instrumentation拦截对象的创建?

问题描述 投票:3回答:2

我需要拦截所有ClassNotFoundException或NoClassDefError的创建:问题在于,其中的某些异常被某些库捕获,并重新抛出为其他异常类型,因此我无法检索类名。Java中是否可以通过使用Intstrumentation来做到这一点?

java exception instrumentation
2个回答
1
投票

0
投票
我不确定如何从我认为您需要的工具中调用回调。

ClassNotFoundException

这需要使用META-INF / MANIFEST.MF像这样编译成JAR文件

System.err.println

并使用程序参数import java.lang.instrument.ClassFileTransformer; import java.lang.instrument.IllegalClassFormatException; import java.lang.instrument.Instrumentation; import java.lang.instrument.UnmodifiableClassException; import java.security.ProtectionDomain; import net.bytebuddy.jar.asm.ClassReader; import net.bytebuddy.jar.asm.ClassVisitor; import net.bytebuddy.jar.asm.ClassWriter; import net.bytebuddy.jar.asm.MethodVisitor; import net.bytebuddy.jar.asm.Opcodes; public class ClassNotFoundExceptionIntercept { public static void premain(String agentArgs, Instrumentation inst) throws UnmodifiableClassException { inst.addTransformer(new ClassFileTransformer() { @Override public byte[] transform(ClassLoader l, String name, Class<?> c, ProtectionDomain d, byte[] b) throws IllegalClassFormatException { if ("java/lang/ClassNotFoundException".equals(name)) { return instrument(b); } return b; } }, true); inst.retransformClasses(java.lang.ClassNotFoundException.class); } private static byte[] instrument(byte[] originalBytes) { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); ClassAdapter adapter = new ClassAdapter(cw); ClassReader cr = new ClassReader(originalBytes); cr.accept(adapter, ClassReader.SKIP_FRAMES); return cw.toByteArray(); } public static class ClassAdapter extends ClassVisitor implements Opcodes { public ClassAdapter(ClassVisitor cv) { super(ASM4, cv); } @Override public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { if ("<init>".equals(name)) { MethodVisitor mv = cv.visitMethod(access, name, descriptor, signature, exceptions); return new Wrapper(mv); } else { return super.visitMethod(access, name, descriptor, signature, exceptions); } } } private static class Wrapper extends MethodVisitor { public Wrapper(MethodVisitor mv) { super(Opcodes.ASM4, mv); } @Override public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { mv.visitMethodInsn(opcode, owner, name, desc, itf); mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "err", "Ljava/io/PrintStream;"); mv.visitLdcInsn("Constructor invoked"); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false); } } } 调用

这可以证明与吞噬异常的测试类一起使用

Manifest-Version: 1.0 Premain-Class: ClassNotFoundExceptionIntercept Agent-Class: ClassNotFoundExceptionIntercept Can-Retransform-Classes: true Can-Redefine-Classes: true

输出

-javaagent:/home/adam/agent-example.jar
© www.soinside.com 2019 - 2024. All rights reserved.