Apache Commons logo Commons BCEL

Application areas

There are many possible application areas for BCEL ranging from class browsers, profilers, byte code optimizers, and compilers to sophisticated run-time analysis tools and extensions to the Java language.

Compilers like the Barat compiler use BCEL to implement a byte code generating back end. Other possible application areas are the static analysis of byte code or examining the run-time behavior of classes by inserting calls to profiling methods into the code. Further examples are extending Java with Eiffel-like assertions, automated delegation, or with the concepts of Aspect-Oriented Programming.
A list of projects using BCEL can be found here.

Class loaders

Class loaders are responsible for loading class files from the file system or other resources and passing the byte code to the Virtual Machine. A custom ClassLoader object may be used to intercept the standard procedure of loading a class, i.e.m the system class loader, and perform some transformations before actually passing the byte code to the JVM.

A possible scenario is described in figure 7: During run-time the Virtual Machine requests a custom class loader to load a given class. But before the JVM actually sees the byte code, the class loader makes a "side-step" and performs some transformation to the class. To make sure that the modified byte code is still valid and does not violate any of the JVM's rules it is checked by the verifier before the JVM finally executes it.


Figure 7: Class loaders

Using class loaders is an elegant way of extending the Java Virtual Machine with new features without actually modifying it. This concept enables developers to use load-time reflection to implement their ideas as opposed to the static reflection supported by the Java Reflection API. Load-time transformations supply the user with a new level of abstraction. He is not strictly tied to the static constraints of the original authors of the classes but may customize the applications with third-party code in order to benefit from new features. Such transformations may be executed on demand and neither interfere with other users, nor alter the original byte code. In fact, class loaders may even create classes ad hoc without loading a file at all.
BCEL has already builtin support for dynamically creating classes, an example is the ProxyCreator class.

Example: Poor Man's Genericity

The former "Poor Man's Genericity" project that extended Java with parameterized classes, for example, used BCEL in two places to generate instances of parameterized classes: During compile-time (with the standard javac with some slightly changed classes) and at run-time using a custom class loader. The compiler puts some additional type information into class files (attributes) which is evaluated at load-time by the class loader. The class loader performs some transformations on the loaded class and passes them to the VM. The following algorithm illustrates how the load method of the class loader fulfills the request for a parameterized class, e.g., Stack<String>

  1. Search for class Stack, load it, and check for a certain class attribute containing additional type information. I.e. the attribute defines the "real" name of the class, i.e., Stack<A>.
  2. Replace all occurrences and references to the formal type A with references to the actual type String. For example the method
  3.             void push(A obj) { ... }
              

    becomes

                void push(String obj) { ... }
              
  4. Return the resulting class to the Virtual Machine.