Cojen's primary goal is making raw Java classfile generation easy, without hiding any of the advanced features. Basic knowledge of how Java classfiles are structured is still required, however. The Virtual Machine Specification is an excellent reference.
Method bytecode is constructed via a builder, in which virtual machine opcodes are represented as slightly higher level instructions. It takes care of selecting optimal opcodes, managing branch labels, computing operand stack depth, choosing local variable registers, and reducing register usage by liveness analysis. In addition, it supports long branches, pushing large string constants onto the stack, boxing and unboxing conversions, and inlining of Java code.
The builder is represented by an interface, which can be used as a visitor into a code disassembler. This feature can be used for just-in-time method mutation, and to aid in understanding how to use the code building facilities.
A simple "Hello World" example is provided which demonstrates the major class generation and loading features. Disassembly tools which can be run from the command line show how any class can be used as an example for class generation.
Defining a new class begins with the construction of a ClassFile object. Use the ClassFile instance to add fields, methods, constructors, inner classes, and to to specify implemented interfaces.
Adding a method causes a MethodInfo object to be returned. Although raw bytecodes can be put into its code attribute, creating a CodeBuilder makes things much easier. Constructing a CodeBuilder around a MethodInfo causes it to take over this responsibility.
ClassFile objects are also used for loading and representing existing classes. Reading a class into a ClassFile object is the first step in disassembling a class. Call one of the defined static readFrom methods to read a class from an input stream. Additional parameters can be supplied to enable reading inner classes and custom attributes.
A "transient" class from Cojen's perspective is one that is dynamically created, never leaves the confines of the current virtual machine process, and whose bytecode is lost when it is unloaded. RuntimeClassFile is used for creating such classes. Internally, it uses a ClassLoader which defines classes, but it never remembers the bytecode used to construct them.
As long as references to the generated class or instances of it still exist, the class will not be unloaded. Once all such references are gone, the class may be unloaded, but it cannot be loaded again by name. It would need to be regenerated.
Cojen provides several powerful utility classes which also serve as examples of how to dynamically generate classes. BeanComparator enables fast custom sorting of Java objects by properties, BeanPropertyAccessor allows object properties to be quickly accessed, and PatternMatcher supports rapid string comparison to patterns containing wildcards.