Revolutionary RMI: Dynamic
class loading
and behavior
objects - JavaWorld - December 1998
Tutorial Details:
Revolutionary RMI: Dynamic class loading and behavior objects
Revolutionary RMI: Dynamic class loading and behavior objects
By: By Andy Krumel
Find out how RMI can help you define extensible, distributed object-oriented frameworks
elcome to Enterprise Java , a new column dedicated to the Java Enterprise APIs: RMI, Java IDL, JDBC, Servlets, and EJB. I originally intended to call this column "Java Enterprise Jumpgate," in reference to the jumpgate technology in the hit TV series Babylon 5. (A jumpgate allows you to move between known points in the universe for trade, exploration, and laying waste -- which is similar to the purpose of the Internet.) I feel the analogy to distributed programming fits: the goal of this column is to demonstrate the capabilities, strengths, and weaknesses of each distributed programming API, helping you jump to new programming destinations. But you know editors, they just won't let you have any fun at their magazine's expense!
A word to the wise: distributed programming is inherently more difficult than standalone programming. However, the Java Enterprise APIs give Java programmers tools to ease the burden of producing robust, efficient applications. This column will help you get production-level, industrial-strength applications out the door, on time and on target.
When it comes to distributed computing, no area is getting more interest today from programmers than the Remote Method Invocation (RMI) API. Programmers love it, Microsoft hates it, and vendors want to make money off of it. EJB, Jini, and JavaSpaces all have their roots in RMI. So what better subject to kick off this column.
Getting excited about RMI
As an instructor, no Java Enterprise API is more rewarding to teach than RMI. It always works the same way:
Introduction
RMI hello world
Callbacks
Object serialization and RMI
The student reactions follow the modules:
Come on, caffeine, work!
Not "hello world" again...
Finally, something I can use
Wow, cool! Can we do that again?
Object serialization and RMI puts a smile on programmers' faces because they witness the subtle strength of RMI: the ability to transport true objects between processes.
What excites students is an example that demonstrates behavior objects. A behavior object is an instance that implements an interface, where the interface declares a remote method parameter type. For example, consider the following interfaces:
public interface ScribbleShape {
public void draw(java.awt.Graphics g);
}
import java.rmi.*;
public interface ScribblePad extends Remote {
public void addShape( ScribbleShape s ) throws RemoteException;
}
The ScribblePad.addShape() method parameter represents a behavior object because the parameter instance must support the ScribbleShape interface, the ScribbleShape interface doesn't extend Remote , and the parameter will be passed between processes using serialization. From the ScribblePad implementation's perspective, the addShape() method is invoked by a Java object running in a process across the network and delivers a serialized version of the ScribbleShape instance that existed in the client process. The ScribblePad implementation can store the parameter value in a Vector , invoke methods on the object, serialize it to a file, or pass to yet another RMI object on a different machine.
All the RMI object knows about that parameter value is that it implements the ScribbleShape interface, exists in its address space (not remote), and supports the draw() method. When the ScribblePad implementation is done with the object, it will be garbage collected; of course, the client's version maintains its own separate state and identity.
In a nutshell, behavior objects are quite useful: they provide a mechanism for defining extensible, distributed object-oriented frameworks. Such frameworks prove useful when implementing the following:
Distributed algorithms. Some parallelized versions of sorting and searching algorithms are well suited to distributed processing. The premise behind implementing these is the presence of heterogeneous systems residing on the network. That is, after all, Java's claim to fame -- placing a homogeneous wrapper around heterogeneous networked systems.
User interfaces to networked services. Ever think about how a smart home would actually be configured? How do you go about controlling all the devices in a manufacturing plant (vision systems, robots, automated testing equipment, and environmental systems)? One method for solving this problem is to remotely load objects from the device that subclasses Panel , which presents controls to configure the device. The remotely loaded panels allow the user to fully customize a networked device without requiring installation of device drivers or special libraries.
Performing tasks within remote servers without being connected or polling. Just think if you could upload your stock object into an online brokerage server and it could monitor continuously, changing stock prices, news, indices, and whatever other parameters you would like, and the stock purchase object would autonomously buy and sell stocks without you having to do a thing. Send in your object and forget about it, no more staying up late to see how the Asian markets did!
Games. Some online games enable players to add weapons that have new powers and behaviors, like autonomously guarding areas or performing sophisticated search patterns. Behavior objects provide the capability to pass these objects into an opponent's space and wreak havoc until the garbage is collected.
RMI class loading
After contemplating the idea of behavior objects, you may start mumbling to yourself: What if the remote object can't locally load the necessary classes to deserialize the behavior object? Well now, that is the question when it comes to RMI. But the answer requires a little under-the-covers RMI, concerning how RMI loads classes when dealing with RMI methods.
From RMI's perspective, class files come in two flavors: code directly used by a program, and everything else. All classes a program compiles to are considered code directly used; this includes all core Java classes along with classes and interfaces used to declare parameters, return types, and variable declarations. Code considered not directly used includes stub and skeleton classes and extended classes of parameters.
When servicing a remote method call, RMI attempts to load marshalled values using one of three class loaders:
AppletClassLoader , if code is running within an applet
The system default class loader, if all classes are directly used by an application
RMIClassLoader to load classes not directly used by the application
So, here's the test:
What class loader is used to load core Java classes ( String , Thread , Component )? Answer: the system default class loader.
What class loader is used to load the ScribbleShape interface when the ScribblePad.addShape() method is invoked by a remote process? Answer: the system default class loader.
What class loader is used to load an implementation of ScribbleShape passed as a parameter to ScribblePad.addShape() ? Answer: the RMIClassLoader, because the parameter instance's class is not directly used by the application.
Congratulations, you all get an A for the day. So where does the RMIClassLoader find the missing class files? Why, from the annotated codebase URL, of course.
The annotated what?
Dynamic class loading
RMI uses serialization to marshall remote method parameters and return values. Specifically, it serializes two values for each parameter: a String representation of a URL from which to remotely load the method value's class, and the serialized value. The act of writing the URL onto the stream is known as annotating the codebase URL.
The codebase URL is determined in one of the following ways:
If the class was loaded by a class loader other than the system's class loader, the class loader codebase is annotated
The value of java.rmi.server.codebase system property
If the codebase system property is not defined, then the codebase URL is null
Thus,
All objects created within an applet are annotated with the applet's codebase
Objects created within a typical application are annotated with the java.rmi.server.codebase system property
Behavior objects created on another machine and passed via an RMI call are loaded from the codebase host from which the object was originally instantiated
So, here's an interesting question: What if the remote object doesn't possess the necessary classes to deserialize the behavior object? RMI will load the classes from the codebase of the invoking process.
But, wait! That's not all. The Java virtual machine requires a security manager be installed to enable remote class loading. For applets, this is a nonissue because a security manager is ever present within Web browsers. Applications require the manual installation of a security manager. The most commonly used security manager to enable dynamic class loading is the RMISecurityManager . Applications usually install a security manager before performing any other functions:
public static void main(String args[]) {
System.setSecurityManager(new RMISecurityManager());
//other application tasks
}
With the introduction of JDK 1.2, you must provide a security policy file when using the RMISecurityManager . Assuming you are on a Windows machine, you can modify the system policy file at java_home\jre\lib\security\java.policy. Alternatively, you can specify a policy file on the command line by setting the java.security.policy system property. That's my approach for this article. The policy file contains:
grant {
// Allow everything for now
permission java.security.AllPermission;
};
For more information on configuring policy files, see the JDK 1.2 security link in the Resources .
An example program
A distributed scribble application helps to demonstrate dynamic class loading and behavior objects
Read
Tutorial at: Click here to view the tutorial
Rate Tutorial: Revolutionary RMI: Dynamic
class loading
and behavior
objects - JavaWorld - December 1998
View Tutorial: Revolutionary RMI: Dynamic
class loading
and behavior
objects - JavaWorld - December 1998
Related
Tutorials:
Automatic Software Distribution of Java Applications
Automatic Software Distribution of Java Applications |
Container support for objects
Container support for objects |
How to write
a Java Card applet: A developer's
guide
How to write
a Java Card applet: A developer's
guide |
Scripting power
saves the day
for your Java
apps
Scripting power
saves the day
for your Java
apps |
The basics of Java class loaders
The basics of Java class loaders |
Reflection
vs. code generation
Reflection
vs. code generation |
Dynamically extend Java applications
Dynamically extend Java applications |
Java security evolution
and concepts, Part 2
Java security evolution
and concepts, Part 2 |
Good
introduction to JDO
Good
introduction to JDO |
Comparison between the two major JDO architectures
Comparison between the two major JDO architectures |
Smartly load your
properties
Smartly load your
properties |
classworlds
classworlds
classworlds is a framework for container developers who require complex manipulation of Java\'s ClassLoaders. Java\'s native ClassLoader mechanims and classes can cause much headache and confusion for certain types of application developers. |
Good
ideas
Good
ideas |
WebOnSwing 1.0 beta
WebOnSwing 1.0 beta
WebOnSwing is a revolutionary multiple environment application framework that allows you to create web applications in the same way you develope a desktop one. You dont need to use JSP files, special tags, XML files, requests, posts |
Object equality
Object equality
Writing equals and hashCode methods for data objects
Summary
In this article, Alex Blewitt describes the two most common methods in the Java language—equals() and hashCode()—and shows how they can be implemented correctly. The |
Inside Class Loaders: Debugging
Inside Class Loaders: Debugging
This article will show how to solve class-loading problems and to overcome some debugging limitations of the JDK class loaders.
|
HeapAnalyzer
What is HeapAnalyzer?
HeapAnalyzer allows the finding of a possible JavaTM heap leak area through its heuristic search engine and analysis of the Java heap dump in Java applications.
Java heap areas define objects, arrays, and classes.
|
Understanding Network Class Loaders Class loaders
One of the cornerstones of Java dynamics, determine when and how classes can be added to a running Java environment. |
Game Canvas Basics
Introduces the MIDP 2.0 GameCanvas class and the game loop concept. Required reading for all aspiring "first person shooter" developers. |
Internals of Java Class Loading
When are two classes not the same? When they're loaded by different class loaders. This is just one of many curious side effects of Java's class-loading system. Binildas Christudas shows how different class loaders relate to one another and how (and why) |
|
|
|