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 4: Line 4:
  
 
===== Mechanism in Java5/Java6 =====
 
===== Mechanism in Java5/Java6 =====
In order to create a Java class at runtime without Java source code, the use of a custom ClassLoaderer is required, along with a bytecode
+
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 library [http://www.java-source.net/open-source/bytecode-libraries framework]).
 
manipulation framework (such as [http://asm.objectweb.org ASM] or some other library [http://www.java-source.net/open-source/bytecode-libraries framework]).
  
Java classloaders form an inheritance-chain at run-time, with the system (<b>Bootstrap</b>, <b>Extension</b> and <b>System</b>) class loaders
+
Java classloaders form an instance-chain 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
 
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.
 
be added to the chain.
Line 15: Line 15:
 
<br />
 
<br />
 
The basic implementation pattern is as follows - in the constructor, the new instance of <code>MyCustomClassLoader</code> is added to the
 
The basic implementation pattern is as follows - in the constructor, the new instance of <code>MyCustomClassLoader</code> is added to the
runtime inheritance-chain by calling <code>super</code> with the parent loader.
+
runtime instance-chain by calling <code>super</code> with the parent loader.
 
<source lang=java5>
 
<source lang=java5>
 
public class MyCustomClassLoader extends ClassLoader {
 
public class MyCustomClassLoader extends ClassLoader {
Line 27: Line 27:
 
         if (some_condition) {
 
         if (some_condition) {
 
             try {
 
             try {
                 byte[] bytes = use_framework_to_generate_bytecodes();
+
                 byte[] bytes = use_framework_to_generate_bytecode();
 
                 return defineClass(className, bytes, 0, bytes.length);
 
                 return defineClass(className, bytes, 0, bytes.length);
 
             }
 
             }
Line 40: Line 40:
 
</source>
 
</source>
  
The <code>findClass</code> method is overridden so that if some condition is met, the bytecodes for the Class <code>className</code> are
+
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 implementation hierarchy which at runtime searches for the class up the instance
 
generated; otherwise, the call is delegated up the implementation hierarchy which at runtime searches for the class up the instance
hierarchy.
+
hierarchy. The implementation hierarchy is responsible for maintaining a cache of both found and generated classes, as well as any
 +
resources that have been loaded (XML descriptor files, image files, etc).
  
 
===== Mechanism in Java7 =====
 
===== Mechanism in Java7 =====

Revision as of 15:53, 31 August 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).

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

Java classloaders form an instance-chain 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-chain 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 implementation hierarchy which at runtime searches for the class up the instance hierarchy. The implementation hierarchy is responsible for maintaining a cache of both found and generated classes, as well as any resources that have been loaded (XML descriptor files, image files, etc).

Mechanism in Java7

Future
JSR-292 (Supporting Dynamically Typed Languages on the Java ™ Platform) introduces a new type of classloader, java.dyn.AnonymousClassLoader. The AnonymousClassLoader class is designed to solve two problems:

  1. Generating many classes with similar bytecode and only minor changes is very inefficient, wasting a lot of precious memory.
  2. Generated bytecode must be contained in a class, which must be contained in a ClassLoader, which keeps a hard reference to the class; as a result, to make even one byte of bytecode garbage-collectable, it must be wrapped in its own class and its own classloader.

First, classes loaded by AnonymousClassLoader are not given full-fledged symbolic names in the global symbol tables; they're given rough numeric identifiers. They are effectively anonymized, allowing much more freedom to generate them at will, since naming conflicts essentially do not happen.

Second, the classes are loaded without a parent ClassLoader, so there's no overprotective mother keeping them on a short leash. When the last normal references to the class disappear, it's eligible for garbage collection like any other object.

Third, it provides a mechanism whereby an existing class can be loaded and slightly modified, producing a new class with those modifications but sharing the rest of its structure and data.

Back to the top