byte-buddy icon indicating copy to clipboard operation
byte-buddy copied to clipboard

how to catch thread Exception?

Open jayrrrrr opened this issue 3 years ago • 10 comments

Hi,author i want use byte-buddy for catch code Exception,but my code use new Thread ,byte-buddy cannot catch new Thread “Cooker" Obejct:

public class Cooker {
    public void hello() {
        System.out.println("+ method name : public void hello();");
        new Thread(new Task()) .start();
    }
}

Task Object:

public class Task implements Runnable{
    @Override
    public void run() {
        System.out.println("jay");
        int a = 1/0;
    }
}

Advice Object:

public class AdviceLogic {
    @Advice.OnMethodExit(onThrowable = Throwable.class)
    public static void exit(@Advice.Thrown Throwable thrown) {
        if (thrown != null){
            System.out.println("- - - - -exception - - - - - -");
            System.out.println("exit!"+ thrown.getClass().getName());
        }
    }
}

TestAdvice Object:

public class TestAdvice {
    public static TestAdvice INSTANCE = new TestAdvice();

    ClassLoader classLoader;

    public void initClassLoader() {
        classLoader = new ByteArrayClassLoader.ChildFirst(getClass().getClassLoader(),
                ClassFileLocator.ForClassLoader.readToNames(Cooker.class),
                ByteArrayClassLoader.PersistenceHandler.MANIFEST);
    }
    public void modifyTarget() throws Exception {
        ByteBuddyAgent.install();
        new AgentBuilder.Default()
                .with(AgentBuilder.PoolStrategy.Default.EXTENDED)
                .with(AgentBuilder.InitializationStrategy.NoOp.INSTANCE)
                .type(ElementMatchers.is(Cooker.class), ElementMatchers.is(classLoader)).transform(new AgentBuilder.Transformer() {
                    @Override
                    public DynamicType.Builder<?> transform(DynamicType.Builder<?> builder, TypeDescription typeDescription, ClassLoader classLoader, JavaModule module) {
                        return builder.visit(Advice.to(AdviceLogic.class).on(ElementMatchers.not(ElementMatchers.isConstructor()).and(ElementMatchers.any())));
                    }
                })
                .installOnByteBuddyAgent();
    }
    public void print() throws Exception {

        Class<Cooker> cookerType = (Class<Cooker>) classLoader.loadClass(Cooker.class.getName());
        Object Cooker = cookerType.getDeclaredConstructor().newInstance();
        cookerType.getDeclaredMethod("hello").invoke(Cooker);


    }
    public static void main(String[] args) throws Exception {
        INSTANCE.initClassLoader();
        INSTANCE.modifyTarget();
        INSTANCE.print();
    }
}

i want to catch the exception in the task ,but i cant

jayrrrrr avatar Aug 24 '22 10:08 jayrrrrr

That's a JVM restriction, unfortunately. One cannot use onThrowable within a constructor.

raphw avatar Aug 24 '22 14:08 raphw

That's a JVM restriction, unfortunately. One cannot use onThrowable within a constructor.

Is there a way to catch the exception of the thread inside the method?

Restlol avatar Aug 25 '22 12:08 Restlol

you could instrument the method that calls the constructor.

raphw avatar Aug 25 '22 15:08 raphw

you could instrument the method that calls the constructor.

sorry sir,I don't understand too much. Can you elaborate on it

jayrrrrr avatar Aug 26 '22 02:08 jayrrrrr

If you need to catch an exception thrown from a constructor, with advice, you cannot instrument the constructor itself. But if the constructor is called from a method, for example a static factory, you can instrument this factory.

raphw avatar Aug 26 '22 09:08 raphw

sorry i am a litter confused. if I don't know that there are threads in the code, but I need to catch exceptions including thread stack exception like this: `public class Cooker { public void hello() { System.out.println("+ method name : public void hello();"); //more Thread // Thread thread1 = new Thread(new Task()); // Thread thread2 = new Thread(new Task()); // Thread thread3 = new Thread(new Task()); // Thread thread4 = new Thread(new Task());

}

} ` How should I do it?

jayrrrrr avatar Aug 26 '22 11:08 jayrrrrr

You could instrument the Task.run method, for instance. If an exception was thrown, advice would capture it.

raphw avatar Aug 26 '22 13:08 raphw

You could instrument the Task.run method, for instance. If an exception was thrown, advice would capture it.

If the thread accepts a lambad, the lambad cannot be instrument?

jayrrrrr avatar Aug 30 '22 01:08 jayrrrrr

No, lambdas cannot normally be instrumented.

raphw avatar Aug 30 '22 07:08 raphw

No, lambdas cannot normally be instrumented.

I see, thank you sir

jayrrrrr avatar Aug 31 '22 02:08 jayrrrrr