SYS-CON Media
 Register Now!
Save $700
Untitled Document
2009 East Gold Sponsors
Untitled Document
2009 East iPhone Gold Sponsors
Untitled Document
2009 East Silver Sponsors
Untitled Document
2009 East Exhibitors
Untitled Document
2009 East Media Sponsors
Untitled Document
2008 West
Platinum Sponsor
Untitled Document
2008 West Gold Sponsors
Untitled Document
2008 West Silver Sponsors
Untitled Document
2008 West Bronze Sponsors
Untitled Document
2008 West Exhibitors
Untitled Document
2008 West Media Sponsors
Untitled Document
2008 East
Platinum Sponsor
Untitled Document
2008 East Gold Sponsors
Untitled Document
2008 East Exhibitors
Untitled Document
2008 East Media Sponsors
Untitled Document
2008 Association Sponsor
Can't Miss RSS Feed
Subscribe to the AJAXWorld.com RSS Feed & Get All The Conference News As It Happens!

2009: Decision Year for RIAs - June 22-23, 2009 New York


Evolutive Java Applications
Evolutive Java Applications

For the past few years I've participated in several projects to update existing Java applications. While working on those projects I often wanted to be able to add new functionality to a class without recompiling it.

Some of the reasons for this were:

  • I didn't have the right to access or modify a class's source file if, for example, the class was developed by a tier supplier.
  • The class was used in many distributed sites and the new functionality was useful for a small number of sites only.
  • There were some persistent objects and I didn't want to manage several versions of the class or update all the persistent objects using a batch mechanism.
  • I didn't want to touch a tested class that had been working well for many months or years.
  • Other developers were working on the same class at the same time and we had to coordinate our modifications to avoid any incompatibility as well as avoid scratching our modifications. It would have been a lot easier if each developer had worked on a different source file associated with its own functionality.
After much thought I decided I didn't want a completely dynamic solution, such as JavaScript, where it's possible to add new functions to a class at runtime. In that kind of language the performance is affected too much and the application architecture becomes difficult to master.

Finally, I created Dynamic Java Binder (DJBinder), a tool that enables you to dynamically attach interface implementations to a class without changing its source file. The dynamically attached interfaces are equivalent to the interfaces listed after the "implements" keywords.

DJBinder uses the class loading mechanism of the Java 2 platform to create the link between the classes and the interfaces at runtime.

How DJBinder Works
An Example Application
I have an application that creates objects of type Man and Woman. Now it's time to add a new print functionality that writes the name and age of each person to the standard output. To reduce the regression risk, the solution can't modify the existing application code.

Listing 1 shows all the definitions used in this example. Note: These classes have not been designed with the intention of using any dynamic mechanism.

First I'll present the Java code you need to write to solve this problem using DJBinder, then I'll explain how DJBinder handles the internal details.

The following statements write the person "p" data to the standard output using the Print interface:

Person p = ... ;
((Print) p).toStandardOutput ();

The cast operation is needed because the Print interface isn't directly implemented by the Person class. The Java compiler assumes that the Print interface is implemented by a Person subclass, but we know this isn't true since neither Man nor Woman implements the Print interface.

The DJBinder method that implements the Print interface without changing the Person class is a new abstract class named DI_Person__ Print:

public abstract class
DI_Person__Print
implements Print {
public void toStandardOutput() {
Person p= (Person) (Object) this;
System.out.println (p.getName());
}
}

The class name is very important because it creates the link between the Person class and the Print interface. The class is abstract since it can't be directly instantiated; its instances are implicitly created by DJBinder according to the cast operations.

The main line of the toStandard- Output() method is:

Person p= (Person) (Object)this;

This enables you to get the Person object that's associated with this interface implementation. The cast isn't done directly because the Java compiler forbids a cast operation between two classes that don't belong to the same hierarchy. The trick is to use an Object class, such as bridge, which is legal because the Object class is the root of all the class hierarchies.

Writing the age is a little more difficult because the age member has a protected visibility that forbids access from the DI_Person__Print class.

The solution proposed by DJBinder is to create a new class with all the protected and private members of the Person class that may be accessed from the DI_Person__* classes. The name of this class must be DA_Person. For example, the following class authorizes access to the age member:

abstract class DA_Person{
public int age;
}

This class makes it possible to use the age member in the toStandard- Output() method :

public abstract class
DI_Person__Print implements Print
{
public void toStandardOutput() {
Person p = (Person) (Object)
this ;
System.out.println
(p.getName()) ;

DA_Person pp = (DA_Person)
(Object) this;
System.out.println (pp.age) ;
}
}

Notice that the object referred to by the pseudo variable "this" is cast to the DA_Person class to access the protected member age. An equivalent alternative would be to cast the variable "p" to the DA_Person class :

DA_Person pp = (DA_Person)
(Object)p;

The final step of my example is to loop over all the persons created by the existing application and cast each person to the Print interface (see Listing 2).

The mechanism implemented by DJBinder is similar to the inner classes of Java. The DI_* classes are similar to inner classes. The most important difference is that each DI_* class is defined in a different source file and can belong to a different JAR file.

The fact that each DI_* class can be extended from another class offers an elegant way to implement the multiple heritage in Java without the problems of other languages such as C++.

The code shown in Listing 2 compiles well, but at runtime there would be several errors if DJBinder didn't use the class loading mechanism to change the bytecode on the fly.

The class loading mechanism works in the following way: every time the Java Virtual Machine needs a new class, it requests the current class loader to return the corresponding bytecode. For example, the default class loader returns the content of a file named className.class. This file is searched in the directories listed in the CLASSPATH environment variable.

The DJBinder class loader works in a different way. First, it gets the original bytecode using the class loader that's normally used by the application, changes it, then returns the modified bytecode to the virtual machine.

The DJBinder tool requires that the JVM uses the DJBinder class loader. For the console programs you simply need to replace the traditional command:

virtualMachinePath javaParameters
applicationName
applicationParameters

with

virtualMachinePath javaParameters
amslib.djbinder.Start
applicationName
applicationParameters

The amslib.djbinder.Start class runs your application using the DJBinder class loader.

For other kinds of Java programs (applets, servlets, JSPs, etc.) there's a similar procedure based on the runtime environment characteristics. For example, if you run your Java application server using the amslib.djbinder.Start class, the beans and servlets become DJBinder aware and can use any interface that's dynamically implemented. The DJBinder class loader changes the original bytecode in four places:

1.The cast operations with an interface of target type
The exceptions eventually thrown by the cast operations are caught and DJBinder tries to find a class named DI_objectClass__interface or DI_objectSuperClass__interface. If one correct class is found, a dynamic interface implementation object (DI_* object) is created and returned, otherwise the original exception is rethrown. The objectSuperClass token represents any class in the hierarchy up to the java.lang.Object.

If the same cast is done twice for the same object, the previous DI_* object is returned instead of creating a new object. This allows you to keep some information within the DI_* objects.

In my example this bytecode change prevents the ClassCastException that should be thrown by the following statement of the PrintAllPersons class (see Listing 2):

Print d= (Print)e.nextElement();

The object returned by the expression e.nextElement() is an instance of Person; normally it can't be cast to the Print interface, but DJBinder creates the corresponding DI_* object, which becomes the result of the cast operation.

2. The cast operations that have a class as target type
If the casted object is a dynamic interface implementation object, DJ- Binder replaces the cast by a reference to the main object, that is, the object that triggered the creation of the DI_* object.

In my example this bytecode change prevents the exceptions that should be thrown by the statements:

Person p= (Person) (Object)this;
DA_Person pp =
(DA_Person) (Object) this;

3. The references to a DA_* class
The DA_* classes are a buildtime artifice and don't exist in the runtime environment. All the references to a DA_XXX class are converted into a reference to the XXX class. In addition, special methods are added to the XXX class to enable controlled access to the private and protected members. The access is allowed from the DI_XXX__* classes only.

In my example this bytecode change enables you to access the protected age member of the Person class.

4. The instanceof and == operations
These operations are modified to get a behavior that's compatible with the result of the cast operation: if a cast operation throws an exception, the corresponding instanceof operation must return false; if a cast operation works silently, the corresponding instanceof operation must return true.

Let's assume that the classes X, DI_X__I, and DI_X__J exist and the "v" variable refers to an object of type X, therefore the cast operations:

(I) v
(J) v

do not throw an exception, and the operations:

v instanceof I
v == (I) v
(J) v == (I) v

return "true."

These changes create the illusion that the main object and the dynamic interface implementation objects are a single object. This simple fact makes programming a lot easier. Figure 1 shows the software architecture allowed by DJBinder.

A final requirement of DJBinder is that the DI_* and DA_* classes must belong to the same package of the main class or to a subpackage named djbinder. For example, if the Person class belongs to the acme.applis package, the DI_Person__Print and DA_Person classes must belong to the acme.applis package or the acme applis.djbinder package.

The djbinder subpackage allows you to use the DJBinder mechanism for classes that belong to a sealed package - a package that can't be modified.

What do software developers and application administrators gain from using DJBinder?

For developers the modification unit is usually the source file. Each source file has a creation and modification date. In large software projects with several developers it's necessary to establish a reservation mechanism to prevent two developers from changing the same file simultaneously, otherwise one of the modifications would be lost. DJBinder allows you to distribute the tasks and responsibilities among the developers better, so each developer can work on a well-defined set of functionalities (grouped within an interface). This feature facilitates the parallel work of several developers (increasing the concurrent engineering), thus reducing the duration of the project.

For customers and administrators the modification unit is the executable file. In a Java application the executable files are the JAR files. DJBinder allows you to build JAR files associated with each functional modification. New functionalities become available when the corresponding JAR file is added to the runtime environment. The JAR files already delivered with the previous versions of the application don't have to be modified. This feature facilitates the administration and reassures customers who are afraid of regressions.

A feature that can be easily designed using DJBinder is virtual typing - using a type that's different from the Java class name to look for a dynamic interface implementation. For example, you could assign the virtual type "French" to an instance of the Person class. In that case the Print interface could be implemented by the DI_French__Print class and include some extra fields. Different instances of the same Person class could have different virtual types. This extra flexibility is very useful, especially to communicate with legacy applications or legacy databases.

Conclusion
DJBinder enables a functionality-driven software architecture that's particularly flexible and makes the evolution of any Java application easier, including existing applications, without recompiling them. DJBinder uses the Java class loading mechanism and doesn't need any special compiler or virtual machine.

For more information about the class loading mechanism see http://java.sun.com/products/jdk/1.2/docs/api/
java/lang/ClassLoader.html
, or contact me at alvaro.schwarzberg@amslib.com. You can download a full version of DJBinder from www.amslib.com/djbinder; however, this version can't be used for commercial development without my written authorization.

About Alvaro Schwarzberg
I have a wide experience in software development that I have acquired over 15 years working for Dassault Systemes, the CAD/CAM world leader, as well as for different international companies based in Colombia, Brazil and the United States. I have participated to several multi-tiered object-oriented applications mixing Java, C++ and databases.

In order to post a comment you need to be registered and logged in.

Register | Sign-in

Reader Feedback: Page 1 of 1

Latest AJAXWorld RIA Stories
An Oracle database provides several v$ views to query information about the database instance, including statistical information that can be used for monitoring and problem analysis purposes. Rene Nyffenegger wrote a nice Summary on Oracle’s v$ views that gives an overview of all...
JavaScript can save your day or it can cause you nightmares. JavaScript and XHR (XmlHttpRequest) enable what the industry considers to be Web 2.0 – meaning highly interactive web sites where some application logic is pushed down to the client into the browsers JavaScript engine. ...
Jinfonet Software, a provider of Java reporting solutions, on Thursday unveiled JReport 10. This new version adds rich visualization and interactive reporting to a robust, agile BI platform, providing embedded operational reporting to developers and self-service reporting to end ...
Sauce Labs on Wednesday announced testing support for Adobe Flex and Flash technologies. Based on Selenium, Sauce OnDemand enables cross-browser web application testing of Adobe Flex and Flash technologies in the cloud. This is the first functional testing product that supports t...
Google's quixotic and poorly executed attempt to do business in China on its terms rather than the Chinese government's has suffered another serious setback. Google's Internet Content Providers (ICP) license to run google.cn expired on Wednesday and the Communist regime told the...
Untitled Document

Call 201 802-3020 or Click Here to Save $700!

Register Today and
Save $700

Your registrations includes: Golden Pass Delegates will receive full conference access on June 22-23, 2009 including: Lunch and Coffee Breaks, and a Collectible Bag. Includes access to all Conference Sessions including the Technical Sessions, Exhibits, Keynotes, Vendor Technology Presentations, and Power Panels.


Sponsorship Opportunities

AJAXWorld offers the undisputed best platform to position your company as a leading vendor in the fast-emerging marketplace for AJAX and Enterprise Web 2.0.


Please call
(201)802-3020



Who Should Attend?

 CTOs & VPs of Engineering
 Directors of Technology
 Sr. User Interface Architects
 Front-End Engineers
 VCs & Industry Analysts
 Directors of Business Development
 Software Engineers
 Senior Architects
 Application Programmers & Software Developers
 Project Managers
 Web Programmers & Designers
 Companies & Organizations that need to stay in
  front of the latest Web technology

AJAXWorld 2009 East - Tracks

Track 01: Business Value of RIAs | Enterprise RIA
Track 02: User Interface & User Experience
Track 03: RIA Tools
Track 04: iPhone Developer Summit



Brought To You By:

AJAXWorld Magazine is the pre-eminent independent vendor-neutral resource for the fastest growing new segment of the software business: entirely Web-based applications and experiences.

Download the Latest Issue!

AJAXWorld 2009 East Speakers Include...


BERGELT
Open Invention Network

BOEDIGHEIMER
Schwans Shared Services

BOSE
DSine Dynamics

GIROUARD
Magnani Caruso Dutton

HERTZOG
NEXThink

WALKER
DotNetNuke Corporation

WESSENDORF
Oracle

YATIV
Magic Software

CARDEN
OpenSpan

CARRATO
IBM

GURNAMI
JP Morgan Chase

FISHER
SpringSource

WHERRY
Meebo

GRABNER
dynaTrace Software

KRZYSKO
US Department of Defense

LOEWY
WebLayers

AJAXWorld Webcasts



SYS-CON EVENTS


AJAXWorld Keynotes & Power Panels

Get “Rich” Quick: Rapid Prototyping for RIA with ZERO Server Code - by Matt Quinlan
Designing for and Managing Performance in the New Frontier of Rich Internet Applications - by Ben Rushlo
REAs: Rich Enterprise Applications - by Pieter Humphrey
Beyond Widgets: What a RIA Platform Should Offer - by Charles Kendrick
How Can AJAX Improve Homeland Security - by Steve Maryka & Ryan Moquin

AJAXWorld Sessions on SYS-CON.TV

· Bill Scott - Yahoo! UI Library
· David Heinemeier Hansson - AJAX on Rails
· Jesse James Garrett - Elements of User Experience
· Dion Hinchcliffe - Real World AJAX
· Eric Miraglia - Open Source AJAX Development
· Paul Rademacher - Mashing Up Your Web Application
· Adam Sah - Google Gadgets
· Doug Crockford - An Introduction to JavaScript
· David Linthicum - Enterprise Web 2.0
· Patrick Grady - The Imagination & Experience Web

AJAXWorld...All The AJAX Rock Stars in One Spot!


Past Events Archive

Cloud Computing Conference & Expo
2009 East

cloudcomputingexpo
2009east.sys-con.com/
Virtualizatoin Conference & Expo
2009 East

virtualizationconference
2009east.sys-con.com/
Cloud Computing Conference & Expo
2008 West

cloudcomputingexpo
2008west.sys-con.com/
SOAWorld Conference & Expo 2008 West
soaworld2008.com/
Virtualization Conference & Expo 2008 West
virtualizationconference
2008west.sys-con.com
AJAXWorld Conference & Expo 2008 West
ajaxoct08.sys-con.com
SOAWorld Conference & Expo 2008 East
soa2008east.sys-con.com
Virtualization Conference & Expo 2008 East
virt2008east.sys-con.com
AJAXWorld 2008 Conference & Expo East
ajaxmar08.sys-con.com
SOAWorld Conference & Expo 2007 West
www.soaworld2007.com
Virtualization Conference & Expo 2007 West
virt2007west.sys-con.com
AJAXWorld 2007 Conference & Expo West
ajaxoct07.sys-con.com

Join Over 10,000 Early AJAX Adopters
Who Have Attended AJAXWorld
• A&R Edelman
• Academic Enterprise
• Accoona Corp [2 delegates]
• Acxiom
• Adams Capital Management
• Adaptive Edge
• Adaptive Path
• Adobe Systems Incorporated [21 delegates]
• Adobe Systems Romania
• Ajax13
• All Risks, Ltd.
• alliance
• Alliance For Community Care
• AlphaDetail Inc
• Altera Corporation
• Amazon.com [6 delegates]
• Appeon Corporation [2 delegates]
• Apple Computer [5 delegates]
• Apress [3 delegates]
• Arkivio
• ASA
• Astute Solutions
• Avaya Inc [2 delegates]
• Avenda Systems
• Avenue A | Razorfish [3 delegates]
• Axcella, LLC [2 delegates]
• Aximsoft
• Azimyth
• Backbase USA Inc. [4 delegates]
• BAE Systems [2 delegates]
• Bank of America [2 delegates]
• Barkley Evergreen & Partners Interactive
• Bayview Financial [2 delegates]
• BEA Systems [3 delegates]
• Billeo
• BMC Software, Inc. [2 delegates]
• Borland Software Corporation
• Bradford Technologies, Inc [2 delegates]
• Brilliance
• Brocade Communications Systems, Inc. [2 delegates]
• Brookside Capital LLC
• Brulant
• Bungee Labs, Inc [6 delegates]
• Bureau of Labor Statistics
• BUZ Interactive
• Cadena Software
• Calix Networks
• Callidus Software [2 delegates]
• Cambia Security
• Carnegie Mellon West
• Cautella, Inc.
• CBSA
• Celequest [3 delegates]
• Change Vision, Inc.
• Charles E. Kenney, CPA
• Charles Schwab & Co., Inc. [8 delegates]

   read more...