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

Difference between revisions of "EclipseLink/Development/Dynamic/def1"

(Mechanism in Java5/Java6)
Line 2: Line 2:
 
===== Dynamic Persistence =====
 
===== Dynamic Persistence =====
 
Dynamic Persistence is defined as the ability to create a persistent entity class and use it within an application without <i>a-priori</i> the Java class existing (no <tt>.class</tt> file on the classpath or in the relevant <tt>.jar/.war</tt> archive).
 
Dynamic Persistence is defined as the ability to create a persistent entity class and use it within an application without <i>a-priori</i> the Java class existing (no <tt>.class</tt> file on the classpath or in the relevant <tt>.jar/.war</tt> 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 [http://asm.objectweb.org ASM] or some other [http://www.java-source.net/open-source/bytecode-libraries library]).
 
 
Java classloaders form an instance-hierarchy at run-time, with the system (<b>Bootstrap</b>, <b>Extension</b> and <b>System</b>) class loaders
 
strictly controlled by the JVM. Once an application is launched (via an Application loader), a new loader <code>MyCustomClassLoader</code> can
 
be added to the chain.
 
 
<br />
 
[[Image:custom_classloader.gif]]
 
<br />
 
The basic implementation pattern is as follows - in the constructor, the new instance of <code>MyCustomClassLoader</code> is added to the
 
runtime instance-hierarchy by calling <code>super</code> with the parent loader.
 
<source lang=java5>
 
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);
 
    }
 
 
}
 
</source>
 
 
The <code>findClass</code> method is overridden so that if some condition is met, the bytecode for the Class <code>className</code> 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 <code>MyCustomClassLoader</code> behaves as a 'proper' class loader in all cases, with the additional capability that non-existent
 
classes can be built/found without their corresponding <tt>.class</tt> files being on the JVM's classpath.
 
 
<b><u>NB</u></b>: it is important to note that two separate instances of <code>MyCustomClassLoader</code> can generate two classes
 
for <code>className</code>. Even though the bytecode is identical, the classes are distinct. When running under a Java EE&trade; container
 
(or an OSGi environment), the class loader hierarchy may be <u>much</u> 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.
 

Revision as of 12:01, 10 September 2009

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

Back to the top