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

Adding the logic to a few classes might be boring, but unless you've thoushands of handlers, that's the way I would go. Keep it simple.

That said,

Game.registerHandler( this );

would be more object-oriented.

An alternative to adding the logic in each class is to introduce a factory that is responsible to instantiate the handlers.

HandlerFactory.createMouseHandler();

And method createMouseHandler contains something like

Handler mh = new MousheHandler();
registerHandler(mh);
return mh;

If you don't want either of these options, I would consider either an aspect framework (maybe AspectJ) or a container for Invertion of Control (maybe Spring IoC). Aspects allow you to annotate your source, and "weave" code at the selected places. An IoC container allows you to control the lifecycle of object (e.g. instantiation). Both use bytecode instrumentation behind the scene.

But if you want to do the instrumentation yourself, I can only compare Javassist and ASM that I used personally.

ASM is low-level, and operates really at the level of java bytecode. You must be familiar with it. The framework is very well designed, the manual is excellent, and it is a great library. One one side it can be complicate to replace patterns of bytecode, because it requires a so-called "stateful" transformation. One the other side, you have full control over the bytecode.

Javassist is more high-level. You do not operate at the raw level of bytecode, a slight higher level, e.g. fields read/write, message send, constructors. Also, it allows you to specify changes using regular java syntax, that is then compiled by the framework. The API is a bit confused, because the project grew over the years. There is documentation about the framework, but not so well centralized as with ASM.


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.