Skip to main content

Notice: This Wiki is now read only and edits are no longer possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

EclipseLink/Development/Dynamic/def1

< EclipseLink‎ | Development‎ | Dynamic
Revision as of 14:46, 3 September 2009 by Unnamed Poltroon (Talk)

Dynamic Persistence

Dynamic Persistence is defined as the ability to create a persistent entity class and use it within an application without a-priori the Java class existing (no .class file on the classpath or in the relevant .jar/.war archive).

Mechanism in Java5/Java6

In order to create a Java class at runtime without Java source code, the use of a custom ClassLoader is required, along with a bytecode manipulation framework (such as ASM or some other library).

Java classloaders form an instance-hierarchy at run-time, with the system (Bootstrap, Extension and System) class loaders strictly controlled by the JVM. Once an application is launched (via an Application loader), a new loader MyCustomClassLoader can be added to the chain.


Custom classloader.gif
The basic implementation pattern is as follows - in the constructor, the new instance of MyCustomClassLoader is added to the runtime instance-hierarchy by calling super with the parent loader.

public class MyCustomClassLoader extends ClassLoader {
 
    public MyCustomClassLoader (ClassLoader parent) {
        super(parent);
    }
 
    @Override
    protected Class<?> findClass(String className) throws ClassNotFoundException {
        if (some_condition) {
            try {
                byte[] bytes = use_framework_to_generate_bytecode();
                return defineClass(className, bytes, 0, bytes.length);
            }
            catch (ClassFormatError cfe) {
                throw new ClassNotFoundException(className, cfe);
            }
        }
        return super.findClass(className);
    }
 
}

The findClass method is overridden so that if some condition is met, the bytecode for the Class className is generated; otherwise, the call is delegated up the instance-hierarchy to search for the class. The implementation hierarchy is responsible for maintaining a cache of classes, as well as any resources that have been loaded (XML descriptor files, image files, etc). Thus, an instance of MyCustomClassLoader behaves as a 'proper' class loader in all cases, with the additional capability that non-existent classes can be built/found without their corresponding .class files being on the JVM's classpath.

NB: it is important to note that two separate instances of MyCustomClassLoader can generate two classes for className. Even though the bytecode is identical, the classes are distinct. When running under a Java EE™ container (or an OSGi environment), the class loader hierarchy may be much more complicated, but the point remains - a custom classloader is required to build classes at runtime; the custom classloader is part of a chain of loaders and each dynamic class is distinct. It is thus incumbent upon the designer to ensure that the correct loader is used throughout the lifecycle of the application.

Back to the top