.

Design of XMLC Page Automatic Page Recompilation

This page contains some brief notes on the design of XMLC automatic page recompilation.

Design Issues

Possible Implementations

Generating classes with unique names

An implementation of automatic class recompilation was developed by a user that created classes with names containing time stamps. This allowed new versions of the class to be loaded in he same class loader. Interface were generated for the classes. They were loaded and recompiled by a factory. This approach was not used because:

Loading derived and generated classes in a new class loader

It is possible to load a recompiled class in another class loader and then return a reference to an object of this class as the interface. This was prototyped by creating a new class loader per recompiled class. However, this is problematic for derived classes. Since the derived class is not recompiled, its not desirable to load it in a new class loader. However this is required, since once the XMLC class loader calls another class loader to load the derived class, there is not way to get back to the XMLC class loader.

It's possible to only load the class hierarchy of the derived class down to the compiled class by examining the hierarchy of the old class and restricting a class loader to load just these classes. This will allow a override DOM building mechanism to continue to work.

This implementation suffers from complexity. Additionally, there is no way to query the inheritance structure without loading it (unless some parsing code is added). Since one has to load the class initially without a filter to know the structure of dependent class there is no control over where the dependent classes are loaded. If the class loader is not the primary class loader for the application, classes maybe loaded into the wrong class loader, causing sharing problems.

Parsing the HTML when the class is loaded

The generated class could re-parse out-of-date files when detected instead of generating the file with compiled code. The performance penalty would occur only when the class is loaded.

However the class must be recompiled to validate the HTML file against the interface and provide a compiled class the next time the page is loaded, so why not get it from that class? The DOM could be obtained directly from an instance of the recompiled class and stored in the out of date class. The syncAccessMethods() method would then initialize the pointers to the access methods.

The big drawback of this approach is that its difficult to do override DOM building. The delegation approach is similar and allows override DOM building to work.

Delegation to the recompiled class

Loading the recompiled class in another class loader and having the objects of the old class delegate method calls to objects of the new class. Doing the delegation on method would require adding checks in every method in the base class and the derived class. Not a lot of overhead, but must be done by all base-class and generate class methods.

The big disadvantage with this approach is that override DOM building is a bit complex to delegate. A way of implementing this is by having an instance of the recompiled class point back to the instance of the out-of-date class. Creation methods in the instance of the old-of-date class call the recompiled class creation method through the delegate pointer. The newer creation method does its thing, however when it calls another creation method, that is done by calling the method in the older class. This method in the old class will immediately call the creation method the recompiled class. This allows these methods to be overridden. It also insures that the order of calling creation methods is defined by the recompiled class, not the out-of-date class.

So lets say we have the part of a page being:

    <TABLE ID=Fred>
       <TR ID=Row1>.....
       ... 
    </TABLE>
Under the override DOM build approached, this would generate a method createElementFred() which would call createElementRow1(). The generated code would look something like this:
HTMLTableElement createElementFred() {
    if (delegate != null) {
        return delegate.createElementFred();
    } else {
        HTMLTableElement elem = document.createElement("TABLE");
        if (delegator != null) {
            $elementRow1 = delegator.createElementRow1();
        } else {
            $elementRow1 = createElementRow1();
        }
        if ($elementRow1 != null) {
            elem.appendChild($elementRow1);
        }
    }    
}
Note that $elementRow1 is the field used by the access method.

This has the disadvantage that the creation methods must be public, rather than protected, which might be confusing.

Implementation Overview

Since override DOM building is not yet implemented and copying the DOM from the recompiled class is simpler and a step towards building the delegation implementation, this approach was taken for this initial implementation. The following is the algorithm for recompilation and reloading using the DOM copying: