Java Network Programming (3rd ed) [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Java Network Programming (3rd ed) [Electronic resources] - نسخه متنی

Harold, Elliotte Rusty

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید








18.6 The java.rmi.server Package


The java.rmi.server package is the most complex of all
the RMI packages; it contains the scaffolding for building remote
objects and thus is used by objects whose methods will be invoked by
clients. The package defines 6 exceptions, 9 interfaces, and 10-12
classes (depending on the Java version). Fortunately, you only need
to be familiar with a few of these in order to write remote objects.
The important classes are the RemoteObject class,
which is the basis for all remote objects; the
RemoteServer class, which extends
RemoteObject; and the
UnicastRemoteObject class, which extends
RemoteServer. Any remote objects you write will
likely either use or extend UnicastRemoteObject.
Clients that call remote methods but are not themselves remote
objects don't use these classes and therefore
don't need to import
java.rmi.server.


18.6.1 The RemoteObject Class


Technically, a remote object is not an
instance of the RemoteObject class but an instance
of any class that implements a Remote interface.
In practice, most remote objects will be instances of a subclass of
java.rmi.server.RemoteObject:

public abstract class RemoteObject extends Object 
implements Remote, Serializable

You can think of this class as a special version of
java.lang.Object for remote objects. It provides
toString( ), hashCode( ),
clone( ), and equals( ) methods
that make sense for remote objects. If you create a remote object
that does not extend RemoteObject, you need to
override these methods yourself.

The equals( ) method compares the remote object
references of two RemoteObjects and returns true
if they point to the same RemoteObject. As with
the equals( ) method in the
Object class, you may want to override this method
to provide a more meaningful definition of equality.

The toString( ) method returns a
String that describes the
RemoteObject. Most of the time, toString() returns the hostname and port from which the remote
object came as well as a reference number for the object. You can
override this method in your own subclasses to provide more
meaningful string representations.

The hashCode( ) method maps a presumably unique
int to each unique object; this integer may be
used as a key in a Hashtable. It returns the same
value for all remote references that refer to the same remote object.
Thus, if a client has several remote references to the same object on
the server, or multiple clients have references to that object, they
should all have the same hash code.

The final instance method in this class is getRef():

public RemoteRef getRef( ) // Java 1.2

This returns a remote reference to the class:

public abstract interface RemoteRef extends Externalizable

There's also one static method,
RemoteObject.toStub( ):

public static Remote toStub(Remote ro) // Java 1.2
throws NoSuchObjectException

RemoteObject.toStub( ) converts a given remote
object into the equivalent stub object for use in the client virtual
machine, which can help you dynamically generate stubs from within
your server without using rmic.


18.6.2 The RemoteServer Class


The RemoteServer class extends
RemoteObject; it is an abstract superclass for
server implementations such as
UnicastRemoteObject. It provides a few simple
utility methods needed by most server objects:

public abstract class RemoteServer extends RemoteObject

UnicastRemoteObject is the most commonly used
subclass of RemoteServer included in the core
library. Two others, Activatable and
ActivationGroup, are found in the
java.rmi.activation package. You can add others
(for example, a UDP or multicast remote server) by writing your own
subclass of RemoteServer.

18.6.2.1 Constructors


RemoteServer has two constructors:

protected RemoteServer( ) 
protected RemoteServer(RemoteRef r)

However, you won't instantiate this class yourself.
Instead, you will instantiate a subclass like
UnicastRemoteObject. That class's
constructor calls one of these protected constructors from the first
line of its constructor.

18.6.2.2 Getting information about the client


The RemoteServer class has one method to locate
the client with which you're communicating:

public static String getClientHost( ) throws ServerNotActiveException

RemoteServer.getClientHost() returns a String that
contains the hostname of the client that invoked the currently
running method. This method throws a
ServerNotActiveException if the current thread is
not running a remote method.

18.6.2.3 Logging


For debugging purposes, it is sometimes useful to see the calls that
are being made to a remote object and the object's
responses. You get a log for a RemoteServer by
passing an OutputStream object to the
setLog( ) method:

public static void setLog(OutputStream out)

Passing null turns off logging. For example, to
see all the calls on System.err (which sends the
log to the Java console), you would write:

myRemoteServer.setLog(System.err);

Here's some log output I collected while debugging
the Fibonacci programs in this chapter:

Sat Apr 29 12:20:36 EDT 2000:RMI:TCP Accept-1:[titan.oit.unc.edu:
sun.rmi.transport.DGCImpl[0:0:0, 2]: java.rmi.dgc.Lease
dirty(java.rmi.server.ObjID[], long, java.rmi.dgc.Lease)]
Fibonacci Server ready.
Sat Apr 29 12:21:27 EDT 2000:RMI:TCP Accept-2:[macfaq.dialup.cloud9.net:
sun.rmi.transport.DGCImpl[0:0:0, 2]: java.rmi.dgc.Lease
dirty(java.rmi.server.ObjID[], long, java.rmi.dgc.Lease)]
Sat Apr 29 12:22:36 EDT 2000:RMI:TCP Accept-3:[macfaq.dialup.cloud9.net:
sun.rmi. transport.DGCImpl[0:0:0, 2]: java.rmi.dgc.Lease
dirty(java.rmi.server.ObjID[], long, java.rmi.dgc.Lease)]
Sat Apr 29 12:22:39 EDT 2000:RMI:TCP Accept-3:[macfaq.dialup.cloud9.net:
FibonacciImpl[0]: java.math.BigInteger getFibonacci(java.math.BigInteger)]
Sat Apr 29 12:22:39 EDT 2000:RMI:TCP Accept-3:[macfaq.dialup.cloud9.net:
FibonacciImpl[0]: java.math.BigInteger getFibonacci(java.math.BigInteger)]

If you want to add extra information to the log along with
what's provided by the
RemoteServer class, you can retrieve the
log's PrintStream with the
getLog( ) method:

public static PrintStream getLog( )

Once you have the print stream, you can write on it to add your own
comments to the log. For example:

PrintStream p = RemoteServer.getLog( );
p.println("There were " + n + " total calls to the remote object.");


18.6.3 The UnicastRemoteObject Class


The
UnicastRemoteObject class is a concrete subclass of
RemoteServer. To create a remote object, you can
extend UnicastRemoteObject and declare that your
subclass implements some subinterface of
java.rmi.Remote. The methods of the interface
provide functionality specific to the class, while the methods of
UnicastRemoteObject handle general remote object
tasks like marshalling and unmarshalling arguments and return values.
All of this happens behind the scenes. As an application programmer,
you don't need to worry about it.

A UnicastRemoteObject runs on a single host, uses
TCP sockets to communicate, and has remote references that do not
remain valid across server restarts. While this is a good
general-purpose framework for remote objects, it is worth noting that
you can implement other kinds of remote objects. For example, you may
want a remote object that uses UDP, or one that remains valid if the
server is restarted, or even one that distributes the load across
multiple servers. To create remote objects with these properties,
extend RemoteServer directly and implement the
abstract methods of that class. However, if you
don't need anything so esoteric,
it's much easier to subclass
UnicastRemoteObject.

The UnicastRemoteObject class has three protected
constructors:

protected UnicastRemoteObject( ) throws RemoteException
protected UnicastRemoteObject(int port) // Java 1.2
throws RemoteException
protected UnicastRemoteObject(int port, RMIClientSocketFactory csf,
RMIServerSocketFactory ssf) throws RemoteException // Java 1.2

When you write a subclass of UnicastRemoteObject,
you call one of these constructors, either explicitly or implicitly,
in the first line of each constructor of your subclass. All three
constructors can throw a RemoteException if the
remote object cannot be created.

The noargs constructor creates a
UnicastRemoteObject that listens on an anonymous
port chosen at runtime. By the way, this is an example of an obscure
situation I mentioned in Chapter 9 and Chapter 10. The server is listening on an anonymous
port. Normally, this situation is next to useless because it is
impossible for clients to locate the server. In this case, clients
locate servers by using a registry that keeps track of the available
servers and the ports they are listening to.

The downside to listening on an anonymous port is that
it's not uncommon for a firewall to block
connections to that port. The next two constructors listen on
specified ports so you can ask the network administrators to allow
traffic for those ports through the firewall.

If the network administrators are uncooperative,
you'll need to use HTTP tunneling or a proxy server
or both. The third constructor also allows you to specify the socket
factories used by this UnicastRemoteObject. In
particular, you can supply a socket factory that returns sockets that
know how to get through the firewall.

The UnicastRemoteObject class has several public
methods:

public Object clone( ) throws CloneNotSupportedException
public static RemoteStub exportObject(Remote r) throws RemoteException
public static Remote exportObject(Remote r, int port)
throws RemoteException // Java 1.2
public static Remote exportObject(Remote r, int port,
RMIClientSocketFactory csf, RMIServerSocketFactory ssf)
throws RemoteException // Java 1.2
public static boolean unexportObject(Remote r, boolean force)
throws NoSuchObjectException // Java 1.2

The clone( ) method simply creates a clone of the
remote object. You call the
UnicastRemoteObject.exportObject( ) to use the
infrastructure that UnicastRemoteObject provides
for an object that can't subclass
UnicastRemoteObject. Similarly, you pass an object
UnicastRemoteObject.unexportObject( ) to stop a
particular remote object from listening for invocations.


18.6.4 Exceptions


The
java.rmi.server package defines a few more
exceptions. The exceptions and their meanings are listed in Table 18-2. All but
java.rmi.server.ServerNotActiveException extend,
directly or indirectly, java.rmi.RemoteException.
All are checked exceptions that must be caught or declared in a
throws clause.

Table 18-2. java.rmi.server exceptions

Exception


Meaning


ExportException


You're trying to export a remote object on a port
that's already in use.


ServerNotActiveException


An attempt was made to invoke a method in a remote object that
wasn't running.


ServerCloneException


An attempt to clone a remote object on the server failed.


SocketSecurityException


This subclass of ExportException is thrown when
the SecurityManager prevents a remote object from
being exported on the requested port.

This chapter has been a fairly quick look at Remote Method
Invocation. For a more detailed treatment, see Java
RMI, by William Grosso
(O'Reilly).


/ 164