HomeDigital EditionSys-Con RadioSearch Java Cd
Advanced Java AWT Book Reviews/Excerpts Client Server Corba Editorials Embedded Java Enterprise Java IDE's Industry Watch Integration Interviews Java Applet Java & Databases Java & Web Services Java Fundamentals Java Native Interface Java Servlets Java Beans J2ME Libraries .NET Object Orientation Observations/IMHO Product Reviews Scalability & Performance Security Server Side Source Code Straight Talking Swing Threads Using Java with others Wireless XML
 

When Sun Microsystems introduced the Java language, professional software engineering and network programming was forever changed. Java's language-level support for platform-independent software development, multithreaded applications, true object-oriented program design, and dynamic class loading have proven to be great tools for fast and inexpensive software prototype design.

In the ever-evolving world of computer networking and software development, programmers often face the difficult issue of the need for newer revisions whenever a new data-type, file format, or image content becomes generally accepted. Much effort was spent designing sophisticated applications that were least sensitive to environment changes, but a true solution was not reached, until the introduction of the Java language, and its support for dynamic class loading and object-oriented methodology. Java provides fast and easy ways to design applets and applications that are capable of handling any type of user-defined data dynamically, without ever re-compiling the application. Moreover, classes designed for dynamic content handling do not have to reside on the local site running the application. Such components may be distributed over a large number of interconnected computer networks or the Internet.

This paper introduces techniques used to design and implement applications for dynamic content handling, through the use of interfaces, dynamic class loading and object inheritance. The discussions are integrated with a real-life example of a Java graphical drawing program. Section Two introduces the motivation and design of applications for dynamic content handling. The next section discusses two different approaches of building classes that provide methods for handling user-defined content: the use of class inheritance and interfaces. Finally, Section Three discusses implementation issues through examples, followed by a small section on loading classes over distributed networks.

Handling Dynamic Content
Imagine that a complex drawing tool capable of understanding multiple image formats and providing its users with hundreds of options has just been designed and implemented. It is about to be marketed when the Internet committee introduces a new file format for bitmapped images. Regardless of how flexible the application was designed to be, it will, most likely, have to be recompiled after implementing the image format converter. Furthermore, the application must be recompiled and redistributed each time new standards are set.

With the introduction of the Java language, this situation is no longer problematic, because applications can be designed to grow dynamically based on the needs of the environment. If the drawing program in the previous example had been written in Java, only two simple steps would be needed to adjust it to the new standards: the writing of the new image format handler, and its posting on the World Wide Web, from where users can download it. Because the code produced by the Java compiler is architecture independent, users across several platforms can link the new module to their application dynamically.

Designing such applications, however, requires a very thorough understanding of the task and a very well thought-out design. Regardless of how these classes are designed, a layer common for all objects will have to be provided. This layer will be used by the applications to communicate with such components. The following section describes two methods used in Java to implement classes that can be used to handle user-defined content and format dynamically.

Object Inheritance and Interfaces
When we think of a mechanic, we think of a person who can fix cars in general. How the mechanic fixes the cars and what type of cars he fixes is a design issue. When designing classes to handle dynamic data, the same idea is used. On an abstract level, a class must be provided that can display a shape on the canvas of the application. Because the shape and attributes of the image are unknown at this point, assumptions about such components should be kept to a minimum. In this example, it is valid to assume that every object, regardless of its shape, has a dimension, a color and a few additional drawing attributes. These attributes, and only these, should be contained in the base class.

Once the base class has been designed, objects can be derived from this implementation to handle the specifics involved with displaying different shapes of objects. The two most commonly used methods of defining subclasses are through class inheritance and the use of interfaces. Although the two methods can be combined, this subject is beyond the scope of this article.

Subclassing Through Inheritance
The advantage of using class inheritance to design subclasses for dynamic handling is that if objects share a common functionality, methods can be defined in the base class for these functions, and only the ones that are content-specific must be re-defined in derived classes. The downside of this technique is that the designer must make sure that the derived classes are compatible with the superclasses in functionality.

Consider the example of the Shape class. Because every shape must be able to display itself on the canvas, the draw() method is implemented in the base class, and the subclasses are allowed to override this method if necessary. Listing 1 shows a sample code fragment using this implementation.

Once this class is defined, it can be extended to handle virtually any shape of object. The implementation of the derived classes will handle the specifics of rectangles, ovals, lines, etc. as shown in Listing 2.

In this example, the draw() method is overwritten to handle shape specific display. Once an object derived from Shape is instantiated, each time the object is redisplayed, the appropriate draw function will be called by the Java interpreter, based on the subclass of the object

Subclassing Using Interfaces
Subclassing using interfaces is another widely used technique for dynamic content handling. This method is preferred when subclasses share little or no common functionality. Also, because Java does not support multiple inheritance, if a class must be derived from another superclass, the interfacing technique must be used to provide dynamic functionality.

Interfaces in Java declare functions (or methods) that subclasses must implement based on their content. Classes implementing these interfaces can then be used for dynamic data handling independent from their internal design or subclass type. Listing 3 illustrates this concept.

This listing also shows how any instance of MyObject can be drawn independently from its internal implementation. It is important to ensure that the superclass has not yet implemented a draw method with the same signature for some other purpose, which would be overlapped by the interface implementation.

Dynamic Loading and Invoking Content Handlers
Once the classes are properly designed, the next step is their implementation. The following is an example of this process:

An input file is given, containing a list of shapes and their descriptions. Each line contains exactly one shape (or a comment), where attributes are separated by colons, the first attribute being guaranteed to be the name of the shape. An example of the input might look like this:

Rectangle:10:10:50:100
Line:50:0:90:250
Circle:90:90:10

The attributes on the lines are shape specific, and each shape must handle them according to its specifications. On the large scale, the following list describes what needs to be done:

Read a line from the input, and get the class name from the line
Load the class dynamically
Initialize the class with the given parameters
Display the given shape
Go back to step 1

Step 1 - Read a line from the input
This step is trivial, and does not require an explanation at this point. It may be assumed that a line has been read in from an InputStream without error, it is not a comment, and that the first token that contains the content handler class's name has been extracted.

Step 2 - Load the class dynamically
Once the class name is obtained from the input script, the next step involves loading it into the runtime environment. Although Java provides a method of loading classes by name, this functionality is limited to loading classes located on the local file system, and must reside in one of the directories defined in the CLASSPATH environment variable. Experienced programmers usually derive their own ClassLoader object, allowing classes and content handlers to be loaded from virtually any Internet site. The design of such classloader is beyond the scope of this paper, and will not be discussed in further detail.

One method is to declare a variable, that is a type of the Drawable interface line this:

Class c = Class.forName( class_name );
Drawable obj = c.newInstance();

where the class_name is the name of the class that needs to be loaded from the disk. In this code fragment, Java will first load and resolve the specified class, and will assign it to the variable c. Note that c is not an instance of any Drawable object, rather it is more like a structure containing information needed to instantiate such a class in line 2.

Steps 3 and 4 - Initializing and displaying the image
Once an instance of a Drawable object has been created, before draw() can be called, the new instance must be initialized. Note that this cannot be done with the use of constructors, because when a Drawable instance in created, its exact subclass type is unknown to the compiler. To overcome this problem, the implementation provides a common init() method to initialize any new instances of the Drawable interface. The init() method, using the remaining string from the input line, will initialize the instance variables of each subclass, as shown in Listing 4. Once obj has been properly initialized based on its parameter list, the call to the draw method can be made, which will display the object according to its specifications. Applications and applets designed in this fashion are extremely flexible, and independent of their environment. If in the future, a Triangle class is implemented, it can immediately be used across platforms, without the need to recompile the original program.

Conclusion
Java's language-level support for object-oriented design and dynamic class loading provides two easy and fast methods for developing applets and applications with dynamic content handlers. The first technique utilizes class inheritance, where content handler classes are usually based on one common base object, implementing only the content specific functionality for the derived classes. The second commonly used method is through the use of interfaces, which allows classes with little or no common functionality to share a common implementation layer used to invoke content specific information processing.

In both cases, the content handler classes are loaded into the run-time environment by name, with the use of the Java ClassLoader object. By deriving classloaders that allow the application to import content handlers over any network, the flexibility of the program can greatly be increased.

Acknowledgments
Special thanks to Dr. Deepinder Sidhu, of the Maryland Center for Telecommunication Research, and Sun Microsystems for the unlimited use of computer resources throughout this project. Finally, I would like to thank Orsi Lazar for her generous help in editing the early versions of this paper.

Related Publications
Ed Tittlel and Mark Gaither. 60 Minute Guide to Java. Internet World. IDG Books Worldwide, Inc. 1995.
Laura Lemay and Charles L. Perkins. Teach Yourself Java in 21 Days. Sams Net Publishing, 1996.
Sashi Lazar. "Building AWT Applications Using Java". Independent research paper, Department of Computer Science, University of Maryland, Baltimore County. March 1996.
Sun Microsystems. "The Java Language Specification". Sun Microsystems, product manual included in JDK version 1.0. Sun Microsystems 1995.
James Gosling and Henry McGilton. "The Java Language Overview: A White Paper". Sun Microsystems Technical Report, May 1995.

About the Author
Sashi Lazar is working on his Ph.D. in Computer Science at the University of Maryland, Baltimore County. He is currently with the Maryland Center for Telecommunication Research sponsored by Sun Microsystems. His work is tightly coupled with two other related topics: Internet security and agent based knowledge retrieval. As part of his research, he is responsible for all Java applications, security, and protocol design. Lazar can be reached at [email protected]

	

Listing 1

class Shape extends Object {
	// Some Class Data containing attributes
	public void draw( Graphics g ) {
		// No code here...
	}
}

Listing 2

class Rectangle extends Shape {
	public void draw( Graphics g ) {
		// Shape specific code goes here
	}
}

Listing 3

public interface Drawable {
	public void draw( Graphics g );
	public void init( String params );
}

public MyObject extends SomeOtherObject implements Drawable {
	public void draw( Graphics g ) {
		// Object specific code goes here...
	}
	// Some other related stuff may go here...
}

Listing 4

obj.init( line );
//... get a Graphics object from somewhere...
obj.draw(g);

 

All Rights Reserved
Copyright ©  2004 SYS-CON Media, Inc.
  E-mail: [email protected]

Java and Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. SYS-CON Publications, Inc. is independent of Sun Microsystems, Inc.