Programming Mobile Objects with Java with CD-ROM

Programming Mobile Objects with Java with CD-ROM

Paperback(BK&CD ROM)

$41.76 $49.99 Save 16% Current price is $41.76, Original price is $49.99. You Save 16%.

Product Details

ISBN-13: 9780471254065
Publisher: Wiley
Publication date: 01/11/1999
Edition description: BK&CD ROM
Pages: 601
Product dimensions: 7.44(w) x 9.23(h) x 1.40(d)

About the Author

JEFF NELSON is a Research Associate with DiaLogos, Incorporated. He is also a trainer with the OMG CORBA Academy, and a regular speaker on CORBA and Java issues at JavaOne, ObjectWorld, and Object Expo.

Read an Excerpt

Chapter 2
Taxonomy of a Mobile Object

Object-oriented software development has led to several advances in the way applications interact with each other. Previously, objects located in different applications communicated with each other by exchanging raw data in the form of packets to distributed objects-they communicated through direct method invocation. Today, we are starting to see the benefits of applications exchanging complete objects, including state and implementation, with each other.
A mobile object application is characterized by an object moving from one application to another. Although this sounds simple in principle, the ramifications are startling. The objects involved may implement network protocols, database access, user interfaces, and other features. They may replace old versions of objects to implement bug fixes or feature upgrades. Objects may broadcast copies of themselves to multiple listeners to provide state replication and fault tolerance. Mobile objects provide a framework for changing the capabilities of an application at run time without restarting the application, recompiling the code, or reinstalling any software. This list just scratches the surface.
Mobile Objects Defined Mobile objects are objects that move between two or more applications. Both the state and the code of the object move from one application to another. Conceptually, this is similar to an application breaking off a piece of itself and giving it to another application. For example, in a mobile object setting, a word processor might break off a mobile object providing the capabilities of a spell checker and send the spell checker object to a text editor. The text editor would then include all the capabilities of spell checker mobile object.
In a Java setting, moving the state of the object is easy because of a facility built into Java called Object Serialization. Object Serialization provides a default, automatic mechanism for reading and writing the state of an object to a data stream. Moving the code for an object is somewhat trickier, but Java ClassLoaders fill this role. A ClassLoader is responsible for locating and loading the byte-code for a Java class, even across the network. ClassLoaders literally load classes. In this manner a network-enabled ClassLoader can actually move the implementation of a Java object across a network to a new computer. For example, AppletClassLoader downloads classes for applets used within a Web document. The protocol it uses for downloading classes is simple HTTP, the same used for almost any Web document. The HTTP protocol also proves an admirable solution to the problem of how to download a class from across the network.
The following code is a small example of a mobile object. This object represents a contact inside a contact database. Contacts like this are common within tools such as mail readers, help desk applications, and marketing support software. Here, each contact has a name, phone number, and e-mail address. The implementation of the object performs tasks such as e-mailing the contact a message.
public class Contact
implements java.io.Serializable
{
public String name;
public String ph;
public String email;

public Contact() {}

// These methods aren't shown for brevity
public void mail(String message) { . }
public void paint(Graphics g) { ... }
public boolean mouseDown(Event evt, int x, int y) { ... }
public boolean keyDown(Event evt, int key) { ... }
};
Listing 2.1 A simple mobile object. Notice that Listing 2.1 not only has state and code, it also paints a user interface as shown by the presence of the paint operation. As this object moves from one application to another, the user interface is made available to other applications at run time. The object also processes its own user input. The user input for this object is rather simple-just a form, as shown in Figure 2.1. The object uses this form to modify the values of its member variables. It also pops up a new Web browser window when the return key is pressed. The mobile object has total control over its own user interface and user input, so it can do anything at all with these.
The example object has the look and feel of any object you might implement in a Java application. Indeed, your own Java code probably has many objects like the preceding one. So what makes this example a mobile object? With the help of a mobile object tool, such as Caffeine, Voyager, or RMI, we can move this object to another application. When we do, its state, code, user interface, and user input all move with it. The state of the object isn't restricted to the application in which it was created. When the state moves, an exact duplicate of the current member variables of the object moves across the network. The application at the receiving end can then use this object, invoking operations on it and accessing its member variables, checking the current balance of the Contact, for example.
The actual byte-code implementation of the Java object is also transmitted across the network and is loaded by the receiving application. The mobile object includes all the methods for the object with their code. When you invoke the charge method on the object, the code for the charge method is invoked in the local application. In the case of this application, a dialog box, shown in Figure 2.2, is popped up to confirm the charge. This dialog box appears on the application that just obtained the mobile object, not the application that originally instantiated the mobile object. Mobile code allows the object to perform any Java operations within the restrictions of the current SecurityManager. Popping up a dialog box is just one example of this type of action. Other examples include writing to a file, implementing a TCP/IP client or server, accessing a database, or performing any other actions of a Java application.
As previously mentioned, the mobile object in Listing 2.1 paints its own user interface. This is just another example of a feature of mobile code. When the object is moved into a new application, the user interface of the object becomes available in that application, as shown in Figure 2.3. Moving the user interface of an object from place to place provides a powerful tool for properly factoring an object model or breaking a particular problem down into a natural set of objects. When you develop a new object, the object may be distributed to already deployed clients without having to replace the clients. Because the new user interface moves along with the object to the clients, it isn't necessary to rewrite and redeploy your entire client base when you want to update the user interface of some of the objects. Of course, many object-oriented developers are familiar with the pitfalls of closely coupling a user interface with an object, following the Model-View-Controller pattern of software development.
Code that heavily mixes user interface code, also called a View, with application logic, also called a Document, quickly becomes difficult to enhance and maintain. The mobile object approach to moving user interface objects across the network does not imply that the Document and View must be merged. When the View is extracted from the client, the implementation of the View becomes easier to modify and deploy because both the View and Document may be maintained on the server side. This does not imply that they must be closely coupled-just that they may evolve together. For example, there's no reason you can't split the user interface of the preceding object into an additional ContactView object as well. The Views of an object may be available as mobile objects!
Mobile code allows mobile objects to accept their own user input. The example object accepts both mouse and keyboard events to allow the end-user to fill out a form to change the values of the mobile object. If you press the return key, this mobile object also pops up a Web page-just another example of mobile code at work.
Listing 2.1 is simple, but not trivial. Mobile objects don't necessarily have to paint a user interface, process user input, or even have state. The following is another example of a mobile object that neither has state or any user interface nor implements any operations at all:
public class Trivial
{
};
This object is so trivial that many experts might challenge its status as a mobile object. Even though the size of the state of this object is zero, it can still be a mobile object. A mobile object isn't required to have state, though the fact that state is preserved is one of the main benefits of object mobility. This object doesn't do anything at all, yet it can still be treated as a mobile object.
The preceding mobile object doesn't implement java.io.Serializable. Implementing this interface is not required for this object to be mobile. The requirement that a mobile object implement java.io.Serializable is imposed by many, but not all, mobile object tools. Object Serialization is used by these tools to copy objects to low-level data streams, but other tools, such as HORB, can convert an object into a mobile object without Object Serialization. Instead, tools such as HORB rely on their own processing of Java objects to serialize them. In such cases, these other tools have their own rules about how objects are serialized and which parts of each object are not serialized. However, because they do not use Object Serialization, the rule in Object Serialization that serializable objects implement java.io.Serializable is no longer mandated.
The most trivial Java object can be treated as a mobile object in some settings as shown by the preceding Trivial class. No specific requirements force mobile objects to utilize any particular API, though Object Serialization is often used. Existing objects may be converted to mobile objects with minimal source code changes. Often, existing code can be used in a mobile object setting with no changes at all. Software developers have very little additional learning required of them when they develop mobile objects because few or no changes to their traditional approach to software development are necessary.
Ramifications When objects can move between applications, entirely new ways of approaching application design quickly become apparent. First and foremost, deployed applications suddenly become flexible. Flexible applications evolve easily and may change the way they utilize resources and paint user interfaces. Flexible applications are easier to expand and enhance with new capabilities. Mobile objects enable applications to be flexible by providing the essential mechanism for moving new objects to and from applications, replacing or upgrading any existing objects in an application, or simply adding to the existing set of objects.
To understand what this flexibility implies for a developer, consider some of the object-oriented applications you have written. Now, imagine being able to arbitrarily replace or add objects, including new classes, to the application at run time. Some of the objects in your application implemented a graphical user interface, which is a good example of an application feature that is normally static. In a mobile object application, the user interface object could simply be replaced with a new user interface at run time.
The inability to change the user interface of already deployed client applications in the traditional approach to client/server software development is just one indication of a large problem with the traditional approach. Local objects are normally given direct access to operating system resources, including painting user interfaces, manipulating files, invoking operating systems commands, accessing threads, communicating over sockets, performing computations on the CPU, and participating in a shared memory. All of these are examples of local resources that are available only to local applications in popular operating systems. In order to expand the capabilities of distributed software, we want to make these resources available to all the objects in a distributed system, not just the objects that are part of deployed client software. Mobile objects provide one approach to consuming these resources in a distributed system. An object that wants these resources can simply move or be sent to the target computer and begin consuming the desired resources. Of course, the object may be subject to limitations imposed by SecurityManagers, quotas, and the like.
Resource consumption is only one side of the coin. Resource management is another. Resource management addresses a broad problem of monitoring, managing, and administrating the ways resources such as memory, hard disk space, threads, and processor are consumed by objects. Normally, any process capable of consuming a resource will also have at least a limited ability to monitor the status of that resource. The traditional approach to distributed object systems addresses only the way objects in different applications may communicate with each other. This approach helps to simplify the ways applications responsible for managing resources communicate with each other. But distributed objects systems don't address the ways the applications that monitor resources may be implemented and installed on the many computers on which resource management might be required. Mobile objects can help address the issue of resource management by moving to the host computer that owns the resources and taking the steps required to monitor and manage the resource. In practice, the design of the Java Virtual Machine makes consuming resources a great deal easier than monitoring their status. For example, the Virtual Machine can create and write data to new files, but it doesn't provide a means of querying for information about available disk space.
However, the benefits of object mobility are not restricted to resource consumption and management. Replacability concepts are not entirely applicable across the board. For example, in any distributed system, applications communicate with a protocol. Web browsers and server communicate using the HTTP protocol. E-mail readers and servers communicate using the SMTP protocol. Normally, the protocol is compiled into an application and is incapable of changing at run time. The protocol is not capable of changing without the reinstallation of a new executable supporting the code for the new protocol. In an object-oriented environment, the protocol may be implemented as a set of objects, often called protocol objects. When mobile objects enter the equation, the next natural step is to replace the protocol objects themselves with new objects sent across the network. This replacement provides a facility for changing the protocol of an application at run time, perhaps to optimize the protocol or to provide an entirely new communication mechanism. Your mail reader probably understands only SMTP and POP3 protocols, but if you swap in a few mobile objects, you might be exchanging real-time audio and video.
Rather than all clients issuing remote invocations on a server, each client may each receive its own copy of the object, then issue more efficient local invocations on its copy. Different benchmarks have found local invocations hundreds of times faster than distributed invocations because of network latency, and once an object is local to the client, network failure does not result in the automatic failure of the object.
Why send e-mail in the form of a simple text message when you can forward a complete object, implementing the behavior of an application such as meeting scheduling or workflow processing? If you exchange spreadsheets with the accounting department or slide presentations with a group of students, don't worry about whether you are using the same version of MS Office on a Windows 32 platform. In a mobile object environment, the software in the form of class files may be loaded by the receiver of the object if required. In Java, anything is an object, so the capability of sending objects to other computers makes anything possible.
Generalizing on the concepts of mobile objects leads to a discussion of mobile components. Components represent a software development approach that defines a common API for reusing software within a simple drag-and-drop framework. Component software development is extremely productive as a result of the simplicity of building applications from simple drag-and-drop operations, without the complexity of correct source code syntax. The component palette in a component software development environment normally shows all the available components that can be used within an application. These components are normally stored on the hard disk as part of the development environment. Adding new components means running an installation process and registering the component inside the development environment. When two developers collaborate on a project, they must manually exchange components periodically through the normal mechanisms of floppy disks, ftp, and installation procedures. Mobile components provide a framework that enables components to move across the network.
Component software development is much like object software development in that a typical application may be built up of many different components interacting. The traditional software development approach requires a component software application to be completed, implemented, and then deployed to the target audience. With mobile components, portions of the application may be expanded by the addition of components or and exchange of existing components. For example, a startup software company could ship an early version of a component application with a relatively primitive Web browser component, then later transmit upgraded versions of the same component to existing customers, automatically upgrading their applications.
Mobile components are useful not just in deploying components to the end-user; they can also be useful for deploying components to other members of an application development team, enabling more effective collaboration. The current approach to collaboration used by many development teams is a source code repository, either on a network hard disk or in a source control system that is shared by all the developers of an application. Mobile components can move themselves as a whole to a common repository. An appropriate mobile component framework might then download these components on demand. Developers could discover new components as they become available inside the repository, and a version history of components rather than a low-level source code tracking system might be available. New versions of components could be automatically pushed to both developers and end users of the mobile component software, eliminating the need for manual installation to improve the capabilities of an application. This style of mobile component development is the next generation of the development process that developers use in building software. See Chapter 10: Dynamic Upgrading for an example of this kind of dynamic upgrading with mobile objects.
The new capabilities of mobile objects also introduce new concerns, such as how well mobile objects interact with multithreading and concurrency. For example, many software developers build active objects, which encapsulate their own threads. An active object is a powerful way of creating objects that automatically respond to their environment. However, Java does not provide a mechanism for serializing a thread as it does for serializing an object. Without developer intervention, a thread cannot move from application to application.
Security is yet another concern. In a distributed object environment, objects are simply communicating with each other by remotely invoking methods. The security of a distributed object environment is generally limited to concerns about the privacy, authentication, and integrity of the arguments and return values of the remote invocation. In a mobile object environment, an object moves from one application to another. Unrestricted, the object might be able to do anything on reaching its destination, even reformat the hard drive. Hosts must have ways of protecting themselves against malicious mobile objects. The reverse is also true. Mobile objects should have ways of protecting themselves from malicious hosts. For example, a mobile object might contain sensitive information such as a customer credit card number. A hostile computer could try to dissect the mobile object in order to obtain unauthorized access to this credit card. Mobile objects need some way of protecting this kind of sensitive information. Chapter 12: Security looks at the state of the art in mobile object security.
Version and dependency resolution also becomes increasingly important in an environment in which objects are mobile. Applications deployed utilizing mobile objects might come into contact with copies of out-of-date software or may become out-of-date themselves over the life of the object. In the typical, static application deployment process, a software application is developed, tested, and deployed entirely by a single team of developers. When new features are added, the team goes through the iteration of develop-test-deploy over again. A mobile object approach radically changes the way software deployment is viewed. No longer is a single monolithic application shipped; instead a small groups of objects may be incrementally deployed to upgrade the capabilities of the application. In such an environment, one set of upgrades may be dependent on another in the same way that software releases and patches are dependent on each other in modern software deployment. A robust mobile object application should be capable of determining if all required components of the system are present and loading those that are not.

Object State
State is where the action for mobile objects begins. The state of an object is a snapshot of the current values of all the member variables of the object. As the object is moving across a process boundary, the state of the object must be copied from one address space to another address space. The state of an object does not include source code in Java, though source code can be part of the state of an object in some weakly typed, interpreted languages. Although mixing state and source code has interesting and complex implications for the way software is developed, a simpler way to view software development is to separate the source code and state of an object. In this book, we differentiate between the source code and state of the object, saying that the source code is included in the implementation of the object because this is true in Java and other strongly typed languages.
Object Serialization provides a nice, automatic facility for copying the state of an object in Java. During the process of serializing a Java object, Object Serialization looks at all the member variables of the Java object and writes these out in turn to a stream. When the same object is read back in from the stream, each of the member variables is read from the stream in the same order. In this manner, Object Serialization can automatically read and write Java objects to a stream without requiring the developer to provide custom code to read and write the object, as required in other programming languages when objects are serialized.
That Object Serialization is such an effective, automated tool for serializing Java objects has led to its having a central role in several mobile object tools, including all those described in this book. The design of Object Serialization thus turns out to be central to the construction of mobile objects. In fact, for nearly all the mobile object tools examined here, with the possible exception of Voyager, Object Serialization perhaps plays a larger role in the implementation of mobile objects than the tool itself. That's because Object Serialization is responsible for providing the magic of copying the object to a stream. The mobile object tools just have to write and read the stream, doing very little else to provide additional mobile object functionality. Object Serialization was designed and built by the same team at JavaSoft that implemented Remote Method Invocation (RMI), discussed in Chapter 6: RMI. The implementation of RMI probably suggested the power of automatic object serialization to the JavaSoft team.
Providing a complete reference for Object Serialization is beyond the scope of this book. However, developers of mobile objects should have a basic awareness of how to create Java objects compatible with Object Serialization. With all the tools examined in this book, Object Serialization is always used to copy a mobile object to a remote application on a computer network, though this may not be the case for some mobile object tools, such as HORB. Mobile objects and Object Serialization are not synonymous; the pervasive use of Object Serialization by the mobile objects tools used in this book is merely a detail of the way these tools are currently implemented.

Serialization and Externalization Object Serialization requires that the serializable object implement one of two special base interfaces: java.io.Serializable or java.io.Externalizable. Object Serialization will attempt to serialize only objects that implement one of these two interfaces. Objects that don't implement one of these two interfaces cannot be used as mobile objects with the tools used in this book. If a software developer incorrectly attempts to use a nonserializable object in a mobile object setting, the object cannot be written and read from the low-level network data stream that is used to communicate between two applications, and an exception is thrown, indicating that the object is not serializable.
Objects that extend java.io.Serializable are automatically serialized to a stream using a set of rules defining how the members of the object should be serialized. An example of such a serializable object is shown in Listing 2.2. This simple serializable object could be used as a mobile object in some software applications. This example demonstrates how easy it is to create a mobile object; very little, if any, additional work is required to convert an existing object into a mobile object.
public class FullName
extends java.io.Serializable
{
public FullName() {}
public String firstName;
public String lastName;
public char middleInitial;
};

Listing 2.2 A serializable mobile object.

Objects that implement java.io.Externalizable must provide their own readExternal and writeExternal methods that are responsible for specifying how an object is written to or read from a stream. Although this task requires much more work from the developer, flexibility is gained in the tradeoff. An Externalizable class can contain any custom code required to sufficiently write and read instances of itself from a stream. For example, in Listing 2.3, an ExternalizableImage class is defined. The built-in Java Image class is not serializable, so a child class responsible for externalizing itself and Image must be developed by hand. The Image object is critical to the development of many Java applications because the Image object is used to represent images and icons present in any kind of user interface.
public class ExternalizableImage
extends java.awt.Image
implements java.io.Externalizable
{
public ExternalizableImage() {}
public writeExternal(ObjectOutput o)
{
o.writeInt(this.getHeight());
o.writeInt(this.getWidth());
// ...
}
public readExternal(ObjectInput o)
{
this.setHeight(o.readInt());
this.setWidth(o.readInt());
// ...
}
};
Listing 2.3 An externalizable mobile object. When externalization routines for the ExternalizableImage object that write out the required member of the Image object are hand coded, a way is established for using Image objects in a mobile object system.
The rules for Object Serialization control how an object implementing java.io.Serializable is serialized. These rules control which member variables are automatically copied into the stream and which are ignored. For example, the static and transient member variables of a class are ignored during automatic serialization. As a developer of mobile object software, you must be aware of these kind of rules so that you don't depend on the static state of an object moving with the rest of the object. However, the developer can force Object Serialization to behave in different ways.
First, the static state of a class is normally associated with the class and not the individual object. In some languages, these are called class variables because the variables may be considered stored in the class rather than the instance. Consider that static variables normally have process scope, meaning that all the static variables in a single process are bundled together. Changing the value of a static variable in one place in a process affects the value of the static variable in any other location in the application. Any object of the appropriate class may access the static variables in the process. Since the static variables are not associated with a particular instance and have process scope, it would appear no easy solution exists regarding what to do with the static variables of an object during serialization. One way of forcing the serialization of the static state of an object is to make the object implement java.io.Externalizable and define readExternal and writeExternal operations that read and write the static state for the object. However, the developer of such an application has to provide all the code required to do this rather than take advantage of the more automatic features of Object Serialization.
In addition, automatic serialization ignores transient variables by design. Transient variables are intended to represent those variables that should not be copied with the state of an object. Transient variables might include constructs like circular references, references to the short-lived Applet object, and the like that should not be serialized with the object. The transient keyword was introduced in the Java language specifically for this purpose.
Nelson/Objects with Java w/CD 2-9 04/10/98

Table of Contents

A Look at Distributed Objects.

Toxonomy of a Mobile Object.

Building Mobile Objects with Caffeine.

COM/DCOM and Java.

Building Mobile Objects with Voyager.

RMI.

Dabbling in Groupware.

Building the Dynamically Upgradable Text Editor.

Clustering.

Securing Mobile Objects.

Trends in Mobile Objects.

Overview of Design Patterns.

MVC [Krasner88].

Remote Proxy [GoF95].

Smart Proxy [Meszaros94].

Actor [GoF95].

Object Group [Maffeis96].

Replication [Nelson98].

Command [GoF95].

Predicate [GoF95].

Composable Views [Krasner88].

Extension [Nelson98].

Smorgasbord [Mowbray97].

Interpreter [GoF95].

Federation [Nelson98].

Bibliography.

Appendix.

Index.

End User License Agreements.

Customer Reviews

Most Helpful Customer Reviews

See All Customer Reviews