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 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.
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.
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>
becomes