Denemelerinizin açıklamasının doğru yön, visitTryCatchBlock
ve visitLabel
işaretleriyle karşılaştığınız gerçek engelin ne olduğu açık değil. İşte iş yapan bir müstakil örnektir:
import java.io.IOException;
import java.lang.reflect.Method;
import org.objectweb.asm.*;
public class EnhanceExceptionHandler {
static class Victim {
public static void hello(boolean doThrow) {
try {
System.out.println("in try");
if(doThrow) {
throw new Exception("just for demonstration");
}
} catch(Exception e){
System.out.println("in catch");
}
}
static void passException(Exception e) {
System.out.println("passException(): "+e);
}
}
public static void main(String[] args)
throws IOException, ReflectiveOperationException {
Class<EnhanceExceptionHandler> outer = EnhanceExceptionHandler.class;
ClassReader classReader=new ClassReader(
outer.getResourceAsStream("EnhanceExceptionHandler$Victim.class"));
ClassWriter classWriter=new ClassWriter(classReader,ClassWriter.COMPUTE_FRAMES);
classReader.accept(new ClassVisitor(Opcodes.ASM5, classWriter) {
private String className;
@Override
public void visit(int version, int access, String name, String signature,
String superName, String[] interfaces) {
className=name;
super.visit(version, access, name, signature, superName, interfaces);
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc,
String signature, String[] exceptions) {
MethodVisitor visitor
= super.visitMethod(access, name, desc, signature, exceptions);
if(name.equals("hello")) {
visitor=new MethodVisitor(Opcodes.ASM5, visitor) {
Label exceptionHandler;
@Override
public void visitLabel(Label label) {
super.visitLabel(label);
if(label==exceptionHandler) {
super.visitInsn(Opcodes.DUP);
super.visitMethodInsn(Opcodes.INVOKESTATIC, className,
"passException", "(Ljava/lang/Exception;)V", false);
}
}
@Override
public void visitTryCatchBlock(
Label start, Label end, Label handler, String type) {
exceptionHandler=handler;
super.visitTryCatchBlock(start, end, handler, type);
}
};
}
return visitor;
}
}, ClassReader.SKIP_FRAMES|ClassReader.SKIP_DEBUG);
byte[] code=classWriter.toByteArray();
Method def=ClassLoader.class.getDeclaredMethod(
"defineClass", String.class, byte[].class, int.class, int.class);
def.setAccessible(true);
Class<?> instrumented=(Class<?>)def.invoke(
outer.getClassLoader(), outer.getName()+"$Victim", code, 0, code.length);
Method hello=instrumented.getMethod("hello", boolean.class);
System.out.println("invoking "+hello+" with false");
hello.invoke(null, false);
System.out.println("invoking "+hello+" with true");
hello.invoke(null, true);
}
}
Gördüğünüz gibi, bu düz ileri ediyor, sadece visitTryCatchBlock
istisna eylemcinin etiketini kaydetmek ve sağ visitLabel
kod pozisyonunu karşılaşmadan sonra istediğiniz kodu enjekte . Gerisi, sınıf dosyasını okumak ve dönüştürmek ve sonucu test amacıyla yüklemek için toplu koddur.
Lütfen bu soruya oy verdikten sonra en azından yorum yazınız. – AKS
Belki birisi, sorununun kendiniz çözmeniz için herhangi bir çaba göstermediğinden aşağıya düşüyor. Şu anda bir başkasının işini yapmasını istiyor. Şu ana kadar yaptığınız kodu gözden geçirin ve probleminizin nerede olduğunu netleştirin. – SubOptimal
Başka seçeneğim olmadığında geldiğim yer burası. Kimse buraya gelmek istemiyor ve başka seçenekler açıksa ayrıntılı soru koyma gayretini almak istemiyor. Buraya gelmeden önce keşfettiğim seçenekleri koymalıyım. – AKS