Search code examples
javabytecodeinstrumentationjava-bytecode-asmbcel

Adding code to a Java class w/ Instrumentation: ASM or BCEL?


I am writing a game engine/library in which I have an event dispatcher class which dispatches events by calling listener methods of "registered" event handler classes. One can register an event handler/listener with the event dispatcher by calling the appropriate dispatcher method.

This obviously leads to some boilerplate code for registering every event handler(and also other aspects of my engine have similar bolierplate code), so I was wondering - how about just using Instrumentation to add in all of the necessary code during loading of the event handler class, so that no explicit registration with the event dispatcher is necessary while coding - the call to the dispatcher's register method is added in automatically when the program is run.

It is my understanding that in order to use Instrumentation one should use some bytecode modifier API. I know of two - ASM and BCEL. Which one should I use? Obviously, this is a somewhat simple task I am trying to do, so I want the one which is easier to learn and better documented.

EDIT: Here is a specific example.

Original event handler class:

@Handler //indicates this this class should be transformed
public class MouseEventHandler implements EventHandler<MouseEvent>
{
    //hidden default constructor
    public void handleEvent(MouseEvent event)
    { ... }
}

After transformation:

@Handler
public class MouseEventHandler implements EventHandler<MouseEvent>
{
    public MouseEventHandler()
    {
        //add this line of code to default constructor
        Game.getEventDispatcher().addEventHandler(this);
    }
    public void handleEvent(MouseEvent event)
    { ... }
}

Solution

  • Java bytecode libraries:

    • ASM is fast and actively developed.
    • BCEL is comparatively slow.
    • Javassist is probably easiest to get started with if you're not familiar with Java bytecode.
    • cglib builds on top of ASM, providing some higher level abstractions.
    • Byte Buddy generates classes via a DSL. Actively maintained and seeing increasing usage.

    I would however consider other options before jumping into bytecode manipulation.