Java RMI [NOOK Book]

Overview

Java RMI contains a wealth of experience in designing and implementing Java's Remote Method Invocation. If you're a novice reader, you will quickly be brought up to speed on why RMI is such a powerful yet easy to use tool for distributed programming, while experts can gain valuable experience for constructing their own enterprise and distributed systems.With Java RMI, you'll learn tips and tricks for making your RMI code excel. The book also provides strategies for working with serialization, threading, the RMI ...

See more details below
Java RMI

Available on NOOK devices and apps  
  • NOOK Devices
  • Samsung Galaxy Tab 4 NOOK
  • NOOK HD/HD+ Tablet
  • NOOK
  • NOOK Color
  • NOOK Tablet
  • Tablet/Phone
  • NOOK for Windows 8 Tablet
  • NOOK for iOS
  • NOOK for Android
  • NOOK Kids for iPad
  • PC/Mac
  • NOOK for Windows 8
  • NOOK for PC
  • NOOK for Mac
  • NOOK for Web

Want a NOOK? Explore Now

NOOK Book (eBook)
$25.49
BN.com price
(Save 42%)$43.99 List Price

Overview

Java RMI contains a wealth of experience in designing and implementing Java's Remote Method Invocation. If you're a novice reader, you will quickly be brought up to speed on why RMI is such a powerful yet easy to use tool for distributed programming, while experts can gain valuable experience for constructing their own enterprise and distributed systems.With Java RMI, you'll learn tips and tricks for making your RMI code excel. The book also provides strategies for working with serialization, threading, the RMI registry, sockets and socket factories, activation, dynamic class downloading, HTTP tunneling, distributed garbage collection, JNDI, and CORBA. In short, a treasure trove of valuable RMI knowledge packed into one book.

Read More Show Less

Product Details

  • ISBN-13: 9781449315351
  • Publisher: O'Reilly Media, Incorporated
  • Publication date: 10/22/2001
  • Sold by: Barnes & Noble
  • Format: eBook
  • Edition number: 1
  • Pages: 576
  • Sales rank: 576,262
  • File size: 6 MB

Meet the Author

William Grosso is a well-known speaker, Java SIG chair, and software architect currently residing in the San Francisco Bay area. He's been working with distributed systems since 1995, lectures for the University of California Berkeley Extension on Enterprise APIs, and is the principal engineer at Hipbone Inc. A former mathematician, he got into programming because it seemed like easy money. He got into distributed computing because he noticed that client-server gurus got the big bucks. And then he started programming in Java because he figured that's where the REAL money was. Having learned the error of his ways, he decided to write a book instead. When not programming or writing, he spends most of his time hiking, drumming, and trying to remember that it was he was about to say.
Read More Show Less

Read an Excerpt

Chapter 10: Serialization

Serialization is the process of converting a set of object instances that contain references to each other into a linear stream of bytes, which can then be sent through a socket, stored to a file, or simply manipulated as a stream of data. Serialization is the mechanism used by RMI to pass objects between JVMs, either as arguments in a method invocation from a client to a server or as return values from a method invocation. In the first section of this book, I referred to this process several times but delayed a detailed discussion until now. In this chapter, we drill down on the serialization mechanism; by the end of it, you will understand exactly how serialization works and how to use it efficiently within your applications.

The Need for Serialization

Envision the banking application while a client is executing a withdrawal. The part of the application we're looking at has the runtime structure shown in Figure 10-1.

What does it mean for the client to pass an instance of Money to the server? At a minimum, it means that the server is able to call public methods on the instance of Money. One way to do this would be to implicitly make Money into a server as well.1 For example, imagine that the client sends the following two pieces of information whenever it passes an instance as an argument:

  • The type of the instance; in this case, Money.
  • A unique identifier for the object (i.e., a logical reference). For example, the address of the instance in memory.

The RMI runtime layer in the server can use this information to construct a stub for the instance of Money, so that whenever the Account server calls a method on what it thinks of as the instance of Money, the method call is relayed over the wire, as shown in Figure 10-2.

Attempting to do things this way has three significant drawbacks:

  • You can't access fields on the objects that have been passed as arguments.

    Stubs work by implementing an interface. They implement the methods in the interface by simply relaying the method invocation across the network. That is, the stub methods take all their arguments and simply marshall them for transport across the wire. Accessing a public field is really just dereferencing a pointer--there is no method invocation and hence, there isn't a method call to forward over the wire.

  • It can result in unacceptable performance due to network latency.

    Even in our simple case, the instance of Account is going to need to call getCents( ) on the instance of Money. This means that a simple call to makeDeposit( ) really involves at least two distinct networked method calls: makeDeposit( ) from the client and getCents( ) from the server.

  • It makes the application much more vulnerable to partial failure.

    Let's say that the server is busy and doesn't get around to handling the request for 30 seconds. If the client crashes in the interim, or if the network goes down, the server cannot process the request at all. Until all data has been requested and sent, the application is particularly vulnerable to partial failures.

This last point is an interesting one. Any time you have an application that requires a long-lasting and durable connection between client and server, you build in a point of failure. The longer the connection needs to last, or the higher the communication bandwidth the connection requires, the more likely the application is to occasionally break down.

TIP:   The original design of the Web, with its stateless connections, serves as a good example of a distributed application that can tolerate almost any transient network failure.

These three reasons imply that what is really needed is a way to copy objects and send them over the wire. That is, instead of turning arguments into implicit servers, arguments need to be completely copied so that no further network calls are needed to complete the remote method invocation. Put another way, we want the result of makeWithdrawal( ) to involve creating a copy of the instance of Money on the server side. The runtime structure should resemble Figure 10-3.

The desire to avoid unnecessary network dependencies has two significant consequences:

  • Once an object is duplicated, the two objects are completely independent of each other.

    Any attempt to keep the copy and the original in sync would involve propagating changes over the network, entirely defeating the reason for making the copy in the first place.

  • The copying mechanism must create deep copies.

    If the instance of Money references another instance, then copies must be made of both instances. Otherwise, when a method is called on the second object, the call must be relayed across the wire. Moreover, all the copies must be made immediately--we can't wait until the second object is accessed to make the copy because the original might change in the meantime.

These two consequences have a very important third consequence:

  • If an object is sent twice, in separate method calls, two copies of the object will be created.

    In addition to arguments to method calls, this holds for objects that are referenced by the arguments. If you pass object A, which has a reference to object C, and in another call you pass object B, which also has a reference to C, you will end up with two distinct copies of C on the receiving side.

Drilling Down on Object Creation

To see why this last point holds, consider a client that executes a withdrawal and then tries to cancel the transaction by making a deposit for the same amount of money. That is, the following lines of code are executed:


server.makeWithdrawal(amount);

.... 

server.makeDeposit(amount);

The client has no way of knowing whether the server still has a copy of amount. After all, the server may have used it and then thrown the copy away once it was done. This means that the client has to marshall amount and send it over the wire to the server.

The RMI runtime can demarshall amount, which is the instance of Money the client sent. However, even if it has the previous object, it has no way (unless equals( ) has been overridden) to tell whether the instance it just demarshalled is equal to the previous object.

More generally, if the object being copied isn't immutable, then the server might change it. In this case, even if the two objects are currently equal, the RMI runtime has no way to tell if the two copies will always be equal and can potentially be replaced by a single copy. To see why, consider our Printer example again. At the end of Chapter 3, we considered a list of possible feature requests that could be made. One of them was the following:

Managers will want to track resource consumption. This will involve logging print requests and, quite possibly, building a set of queries that can be run against the printer's log.

This can be implemented by adding a few more fields to DocumentDescription and having the server store an indexed log of all the DocumentDescription objects it has received. For example, we may add the following fields to DocumentDescription:


public Time whenPrinted;

public Person sender;

public boolean printSucceeded;

Now consider what happens when the user actually wants to print two copies of the same document. The client application could call:


server.printDocument(document);

twice with the "same" instance of DocumentDescription. And it would be an error for the RMI runtime to create only one instance of DocumentDescription on the server side. Even though the "same" object is passed into the server twice, it is passed as parts of distinct requests and therefore as different objects.

TIP:   This is true even if the runtime can tell that the two instances of DocumentDescription are equal when it finishes demarshalling. An implementation of a printer may well have a notion of a job queue that holds instances of DocumentDescription. So our client makes the first call, and the copy of document is placed in the queue (say, at number 5), but not edited because the document hasn't been printed yet. Then our client makes the second call. At this point, the two copies of document are equal. However, we don't want to place the same object in the printer queue twice. We want to place distinct copies in the printer queue.

Thus, we come to the following conclusion: network latency, and the desire to avoid vulnerability to partial failures, force us to have a deep copy mechanism for most arguments to a remote method invocation. This copying mechanism has to make deep copies, and it cannot perform any validation to eliminate "extra" copies across methods.

TIP:   While this discussion provides examples of implementation decisions that force two copies to occur, it's important to note that, even without such examples, clients should be written as if the servers make independent copies. That is, clients are written to use interfaces. They should not, and cannot, make assumptions about server-side implementations of the interfaces.

Using Serialization

Serialization is a mechanism built into the core Java libraries for writing a graph of objects into a stream of data. This stream of data can then be programmatically manipulated, and a deep copy of the objects can be made by reversing the process. This reversal is often called deserialization.

In particular, there are three main uses of serialization:

As a persistence mechanism
If the stream being used is FileOutputStream, then the data will automatically be written to a file.
As a copy mechanism
If the stream being used is ByteArrayOutputStream, then the data will be written to a byte array in memory. This byte array can then be used to create duplicates of the original objects.
As a communication mechanism
If the stream being used comes from a socket, then the data will automatically be sent over the wire to the receiving socket, at which point another program will decide what to do.

The important thing to note is that the use of serialization is independent of the serialization algorithm itself. If we have a serializable class, we can save it to a file or make a copy of it simply by changing the way we use the output of the serialization mechanism.

As you might expect, serialization is implemented using a pair of streams. Even though the code that underlies serialization is quite complex, the way you invoke it is designed to make serialization as transparent as possible to Java developers. To serialize an object, create an instance of ObjectOutputStream and call the writeObject( ) method; to read in a serialized object, create an instance of ObjectInputStream and call the readObject( ) object....

Read More Show Less

Table of Contents

Preface
Pt. I Designing and Building: The Basics of RMI Applications
1 Streams 3
2 Sockets 19
3 A Socket-Based Printer Server 49
4 The Same Server, Written Using RMI 65
5 Introducing the Bank Example 83
6 Deciding on the Remote Server 94
7 Designing the Remote Interface 111
8 Implementing the Bank Server 133
9 The Rest of the Application 144
Pt. II Drilling Down: Scalability
10 Serialization 159
11 Threads 198
12 Implementing Threading 229
13 Testing a Distributed Application 276
14 The RMI Registry 288
15 Naming Services 303
16 The RMI Runtime 351
17 Factories and the Activation Framework 375
Pt. III Advanced Topics
18 Using Custom Sockets 411
19 Dynamic Classloading 424
20 Security Policies 443
21 Multithreaded Clients 460
22 HTTP Tunneling 482
23 RMI, CORBA, and RMI/IIOP 503
Index 521
Read More Show Less

Customer Reviews

Average Rating 3
( 1 )
Rating Distribution

5 Star

(0)

4 Star

(0)

3 Star

(1)

2 Star

(0)

1 Star

(0)

Your Rating:

Your Name: Create a Pen Name or

Barnes & Noble.com Review Rules

Our reader reviews allow you to share your comments on titles you liked, or didn't, with others. By submitting an online review, you are representing to Barnes & Noble.com that all information contained in your review is original and accurate in all respects, and that the submission of such content by you and the posting of such content by Barnes & Noble.com does not and will not violate the rights of any third party. Please follow the rules below to help ensure that your review can be posted.

Reviews by Our Customers Under the Age of 13

We highly value and respect everyone's opinion concerning the titles we offer. However, we cannot allow persons under the age of 13 to have accounts at BN.com or to post customer reviews. Please see our Terms of Use for more details.

What to exclude from your review:

Please do not write about reviews, commentary, or information posted on the product page. If you see any errors in the information on the product page, please send us an email.

Reviews should not contain any of the following:

  • - HTML tags, profanity, obscenities, vulgarities, or comments that defame anyone
  • - Time-sensitive information such as tour dates, signings, lectures, etc.
  • - Single-word reviews. Other people will read your review to discover why you liked or didn't like the title. Be descriptive.
  • - Comments focusing on the author or that may ruin the ending for others
  • - Phone numbers, addresses, URLs
  • - Pricing and availability information or alternative ordering information
  • - Advertisements or commercial solicitation

Reminder:

  • - By submitting a review, you grant to Barnes & Noble.com and its sublicensees the royalty-free, perpetual, irrevocable right and license to use the review in accordance with the Barnes & Noble.com Terms of Use.
  • - Barnes & Noble.com reserves the right not to post any review -- particularly those that do not follow the terms and conditions of these Rules. Barnes & Noble.com also reserves the right to remove any review at any time without notice.
  • - See Terms of Use for other conditions and disclaimers.
Search for Products You'd Like to Recommend

Recommend other products that relate to your review. Just search for them below and share!

Create a Pen Name

Your Pen Name is your unique identity on BN.com. It will appear on the reviews you write and other website activities. Your Pen Name cannot be edited, changed or deleted once submitted.

 
Your Pen Name can be any combination of alphanumeric characters (plus - and _), and must be at least two characters long.

Continue Anonymously
Sort by: Showing 1 Customer Reviews
  • Anonymous

    Posted April 1, 2003

    Do not buy

    Some aspects he focus heavily on but some aspects he doesnt. I had to buy several other books to try to understand what he was talking about. If you want to do RMI, you might as well go read the RMi specification, much easier that way. For beginners, you should really get Java Network Programming by Rusty Harold to get some understanding on network programming, since RMI is built on top of this.

    Was this review helpful? Yes  No   Report this review
Sort by: Showing 1 Customer Reviews

If you find inappropriate content, please report it to Barnes & Noble
Why is this product inappropriate?
Comments (optional)