ludovic Bertin wrote:
I'm stuck in trying to intercept a stateless session bean...
If I set the bean class name and method into the rule, Byteman rule is never called.
If I set the local interface name and method into the rule, Byteman is called, but outside of JEE/CDI interceptors.
What is the safe way to proceed ?
I am afraid you may be stuck here with not being able to use Byteman to intercept the SessionBean API methods. The class+method you want to inject into gets hijacked by the code which manages session beans and has its bytecode modified *before* Byteman gets a chance to inject the changes it wants to make. Those changes might well involve renaming the target method or, perhaps, modifying it in such a way that your rule no longer matches it (e.g. they might add an extra parameter to the signature). I don't really know enough detail about what the session bean does to advise you how to work around this. Indeed, depending on what strategy the session bean code uses there may not be a workaround.
This is an example of a more general problem that changes made by one bytecode transformer may invalidate changes that a later transformer wishes to make. What that means really depends on how each of the different transformation processes is performed. If Byteman knew more about what the session bean code does it might be able to still inject the changes you want but only if the session bean code left enough information around for Byteman to work out what the orignal bytecode looked like.
This problem is a two-way street. If Byteman ran first then that might cause problems for the session bean transformer (although I think it probably would not affect it). However, I think that's all a bit academic as I don't think you have any choice about the order of tarnsformation. When transformation is done by multiple agents the order of application is determined by the order in which the agents are installed. So, for example, when using say Byteman and a profiler that uses an agent you could load Byteman on the command line either before or after the profiler to see if you can avoid clashes between the transformation strategies. Unfortunately, in this case of JEE/CDI I believe the session bean code does its transformation in the classloader i.e. it makes changes to the class bytes after they have read from the file but before passing them into ClassLoader.defineClass. The point where agents get a chance to modify the bytecode is under the call to defineClass. So, you cannot re-order the transformations to put Byteman first.
If you can find out more about what the session bean code does to modify the target class you may still be able to come up with a Byteman rule that does inject into the right place. Your interface rule is almost certainly being injected into a Proxy instance for a Proxy class generated by the EE code. That proxy will implement the local interface by setting up the session bean context and then forwarding a call to the transformed version of the session bean class. The Proxy will use a call to Method.invoke to make the indirect call. You could try stepping through the proxy call in a debugger (or just break code inside the Bean and walk back up the stack) to inspect the target method to find out what its class, name and signature are. That might help you identify a rule that actually works. If you can find any more details then post them as I may be able to help devise a rule that does what you want.
First, thanks for your answer.
I managed to intercept my bean with this rule :
METHOD doMethodInterception(InvocationContext, InterceptionType, WeldInterceptorInstances, InterceptorBindings)
AT INVOKE javax.interceptor.InvocationContext.proceed()
DO traceln($CLASS+" - (Method doMethodInterception) Interceptor bindings == null, proceeding with the next stage of invocation processing.")
but that works only for ENTRY and/or EXIT. I lost the benefits of more precise AT <XXX> interception point.
One idea should be to delegate a part of the code to a different class, but it makes me modify existing code to be able to do interception.
The idea behind all of this, is to be able to have a production server copy, and inject some incident, without modifying artifacts.
Maybe there are other approaches than just byteman rule..,
Well, that's some sort of progress. Well done for getting that far.
It might be worth posting to the JBoss EJB3 forum to ask if it is possible to write a Byteman rule which will intercept the EJB target method that this interceptor is wrapping. There are people on that list who know a lot about more about what the interceptor code does than I do. Quite a few of them will also know enough about Byteman to say whether what you want to do is possible.