Sie sind auf Seite 1von 11

Java RMI

Introduction
This is a brief introduction to Java Remote Method Invocation (RMI). Java RMI is a
mechanism that allows one to invoke a method on an object that exists in another address
space. The other address space could be on the same machine or a different one. The RMI
mechanism is basicall an object!oriented R"# mechanism. #$R%& is another object!
oriented R"# mechanism. #$R%& differs from Java RMI in a number of was'
(. #$R%& is a lan)ua)e!independent standard.
*. #$R%& includes man other mechanisms in its standard (such as a standard for
T" monitors) none of which are part of Java RMI.
+. There is also no notion of an ,object re-uest broker, in Java RMI.
Java RMI has recentl been evolvin) toward becomin) more compatible with #$R%&.
In particular. there is now a form of RMI called RMI/II$" (,RMI over II$",) that uses
the Internet Inter!$R% "rotocol (II$") of #$R%& as the underlin) protocol for RMI
communication.
This tutorial attempts to show the essence of RMI. without discussin) an extraneous
features. 0un has provided a 1uide to RMI. but it includes a lot of material that is not
relevant to RMI itself. 2or example. it discusses how to incorporate RMI into an &pplet.
how to use packa)es and how to place compiled classes in a different director than the
source code. &ll of these are interestin) in themselves. but the have nothin) at all to do
with RMI. &s a result. 0un3s )uide is unnecessaril confusin). Moreover. 0un3s )uide and
examples omit a number of details that are important for RMI.
There are three processes that participate in supportin) remote method invocation.
(. The #lient is the process that is invokin) a method on a remote object.
*. The 0erver is the process that owns the remote object. The remote object is an
ordinar object in the address space of the server process.
+. The $bject Re)istr is a name server that relates objects with names. $bjects are
re)istered with the $bject Re)istr. $nce an object has been re)istered. one can
use the $bject Re)istr to obtain access to a remote object usin) the name of the
object.
In this tutorial. we will )ive an example of a #lient and a 0erver that solve the classical
,4ello. world5, problem. 6ou should tr extractin) the code that is presented and runnin)
it on our own computer.
There are two kinds of classes that can be used in Java RMI.
(. & Remote class is one whose instances can be used remotel. &n object of such a
class can be referenced in two different was'
(. 7ithin the address space where the object was constructed. the object is an
ordinar object which can be used like an other object.
*. 7ithin other address spaces. the object can be referenced usin) an object
handle. 7hile there are limitations on how one can use an object handle
compared to an object. for the most part one can use object handles in the
same wa as an ordinar object.
2or simplicit. an instance of a Remote class will be called a remote object.
*. & 0eriali8able class is one whose instances can be copied from one address space
to another. &n instance of a 0eriali8able class will be called a seriali8able object.
In other words. a seriali8able object is one that can be marshaled. 9ote that this
concept has no connection to the concept of seriali8abilit in database
mana)ement sstems.
If a seriali8able object is passed as a parameter (or return value) of a remote
method invocation. then the value of the object will be copied from one address
space to the other. % contrast if a remote object is passed as a parameter (or
return value). then the object handle will be copied from one address space to the
other.
$ne mi)ht naturall wonder what would happen if a class were both Remote and
0eriali8able. 7hile this mi)ht be possible in theor. it is a poor desi)n to mix these two
notions as it makes the desi)n difficult to understand.
0eriali8able #lasses
7e now consider how to desi)n Remote and 0eriali8able classes. The easier of the two is
a 0eriali8able class. & class is 0eriali8able if it implements the java.io.0eriali8able
interface. 0ubclasses of a 0eriali8able class are also 0eriali8able. Man of the standard
classes are 0eriali8able. so a subclass of one of these is automaticall also 0eriali8able.
9ormall. an data within a 0eriali8able class should also be 0eriali8able. &lthou)h there
are was to include non!seriali8able objects within a seriali8able objects. it is awkward to
do so. 0ee the documentation of java.io.0eriali8able for more information about this.
:sin) a seriali8able object in a remote method invocation is strai)htforward. $ne simpl
passes the object usin) a parameter or as the return value. The tpe of the parameter or
return value is the 0eriali8able class. 9ote that both the #lient and 0erver pro)rams must
have access to the definition of an 0eriali8able class that is bein) used. If the #lient and
0erver pro)rams are on different machines. then class definitions of 0eriali8able classes
ma have to be downloaded from one machine to the other. 0uch a download could
violate sstem securit. This problem is discussed in the 0ecurit section.
The onl 0eriali8able class that will be used in the ,4ello. world5, example is the 0trin)
class. so no problems with securit arise.
Remote #lasses and Interfaces
9ext consider how to define a Remote class. This is more difficult than definin) a
0eriali8able class. & Remote class has two parts' the interface and the class itself. The
Remote interface must have the followin) properties'
(. The interface must be public.
*. The interface must extend the interface java.rmi.Remote.
+. ;ver method in the interface must declare that it throws
java.rmi.Remote;xception. $ther exceptions ma also be thrown.
The Remote class itself has the followin) properties'
(. It must implement a Remote interface.
*. It should extend the java.rmi.server.:nicastRemote$bject class. $bjects of such a
class exist in the address space of the server and can be invoked remotel. 7hile
there are other was to define a Remote class. this is the simplest wa to ensure
that objects of a class can be used as remote objects. 0ee the documentation of the
java.rmi.server packa)e for more information.
+. It can have methods that are not in its Remote interface. These can onl be
invoked locall.
:nlike the case of a 0eriali8able class. it is not necessar for both the #lient and the
0erver to have access to the definition of the Remote class. The 0erver re-uires the
definition of both the Remote class and the Remote interface. but the #lient onl uses the
Remote interface. Rou)hl speakin). the Remote interface represents the tpe of an
object handle. while the Remote class represents the tpe of an object. If a remote object
is bein) used remotel. its tpe must be declared to be the tpe of the Remote interface.
not the tpe of the Remote class.
In the example pro)ram. we need a Remote class and its correspondin) Remote interface.
7e call these 4ello and 4elloInterface. respectivel. 4ere is the file 4elloInterface.java'
import java.rmi.<=
/<<
< Remote Interface for the ,4ello. world5, example.
</
public interface 4elloInterface extends Remote >
/<<
< Remotel invocable method.
< ?return the messa)e of the remote object. such as ,4ello. world5,.
< ?exception Remote;xception if the remote invocation fails.
</
public 0trin) sa() throws Remote;xception=
@
4ere is the file 4ello.java'
import java.rmi.<=
import java.rmi.server.<=
/<<
< Remote #lass for the ,4ello. world5, example.
</
public class 4ello extends :nicastRemote$bject implements 4elloInterface >
private 0trin) messa)e=
/<<
< #onstruct a remote object
< ?param ms) the messa)e of the remote object. such as ,4ello. world5,.
< ?exception Remote;xception if the object handle cannot be constructed.
</
public 4ello (0trin) ms)) throws Remote;xception >
messa)e A ms)=
@
/<<
< Implementation of the remotel invocable method.
< ?return the messa)e of the remote object. such as ,4ello. world5,.
< ?exception Remote;xception if the remote invocation fails.
</
public 0trin) sa() throws Remote;xception >
return messa)e=
@
@
&ll of the Remote interfaces and classes should be compiled usin) javac. $nce this has
been completed. the stubs and skeletons for the Remote interfaces should be compiled b
usin) the rmic stub compiler. The stub and skeleton of the example Remote interface are
compiled with the command'
rmic Hello
The onl problem one mi)ht encounter with this command is that rmic mi)ht not be able
to find the files 4ello.class and 4elloInterface.class even thou)h the are in the same
director where rmic is bein) executed. If this happens to ou. then tr settin) the
#B&00"&T4 environment variable to the current director. as in the followin)
command'
setenv #B&00"&T4 .
If our #B&00"&T4 variable alread has some directories in it. then ou mi)ht want to
add the current director to the others.
"ro)rammin) a #lient
4avin) described how to define Remote and 0eriali8able classes. we now discuss how to
pro)ram the #lient and 0erver. The #lient itself is just a Java pro)ram. It need not be part
of a Remote or 0eriali8able class. althou)h it will use Remote and 0eriali8able classes.
& remote method invocation can return a remote object as its return value. but one must
have a remote object in order to perform a remote method invocation. 0o to obtain a
remote object one must alread have one. &ccordin)l. there must be a separate
mechanism for obtainin) the first remote object. The $bject Re)istr fulfills this
re-uirement. It allows one to obtain a remote object usin) onl the name of the remote
object.
The name of a remote object includes the followin) information'
(. The Internet name (or address) of the machine that is runnin) the $bject Re)istr
with which the remote object is bein) re)istered. If the $bject Re)istr is runnin)
on the same machine as the one that is makin) the re-uest. then the name of the
machine can be omitted.
*. The port to which the $bject Re)istr is listenin). If the $bject Re)istr is
listenin) to the default port. (CDD. then this does not have to be included in the
name.
+. The local name of the remote object within the $bject Re)istr.
4ere is the example #lient pro)ram'
/<<
< #lient pro)ram for the ,4ello. world5, example.
< ?param ar)v The command line ar)uments which are i)nored.
</
public static void main (0trin)EF ar)v) >
tr >
4elloInterface hello A
(4elloInterface) 9amin).lookup (,//ortles.ccs.neu.edu/4ello,)=
0stem.out.println (hello.sa())=
@ catch (;xception e) >
0stem.out.println (,4ello#lient exception' , G e)= @ @
The 9amin).lookup method obtains an object handle from the $bject Re)istr runnin)
on ortles.ccs.neu.edu and listenin) to the default port. 9ote that the result of
9amin).lookup must be cast to the tpe of the Remote interface.
The remote method invocation in the example #lient is hello.sa(). It returns a 0trin)
which is then printed. & remote method invocation can return a 0trin) object because
0trin) is a 0eriali8able class.
The code for the #lient can be placed in an convenient class. In the example #lient. it
was placed in a class 4ello#lient that contains onl the pro)ram above.
"ro)rammin) a 0erver
The 0erver itself is just a Java pro)ram. It need not be a Remote or 0eriali8able class.
althou)h it will use them. The 0erver does have some responsibilities'
(. If class definitions for 0eriali8able classes need to be downloaded from another
machine. then the securit polic of our pro)ram must be modified. Java
provides a securit mana)er class called RMI0ecuritMana)er for this purpose.
The RMI0ecuritMana)er defines a securit polic that allows the downloadin)
of 0eriali8able classes from another machine. The ,4ello. 7orld5, example does
not need such downloads. since the onl 0eriali8able class it uses is 0trin). &s a
result it isn3t necessar to modif the securit polic for the example pro)ram. If
our pro)ram defines 0eriali8able classes that need to be downloaded to another
machine. then insert the statement 0stem.set0ecuritMana)er (new
RMI0ecuritMana)er())= as the first statement in the main pro)ram below. If this
does not work for our pro)ram. then ou should consult the 0ecurit section
below.
*. &t least one remote object must be re)istered with the $bject Re)istr. The
statement for this is' 9amin).rebind (object9ame. object)= where object is the
remote object bein) re)istered. and object9ame is the 0trin) that names the
remote object.
4ere is the example 0erver'
/<<
< 0erver pro)ram for the ,4ello. world5, example.
< ?param ar)v The command line ar)uments which are i)nored.
</
public static void main (0trin)EF ar)v) >
tr >
9amin).rebind (,4ello,. new 4ello (,4ello. world5,))=
0stem.out.println (,4ello 0erver is read.,)=
@ catch (;xception e) >
0stem.out.println (,4ello 0erver failed' , G e)=
@
@
The rmire)istr $bject Re)istr onl accepts re-uests to bind and unbind objects runnin)
on the same machine. so it is never necessar to specif the name of the machine when
one is re)isterin) an object.
The code for the 0erver can be placed in an convenient class. In the example 0erver. it
was placed in a class 4ello0erver that contains onl the pro)ram above.
0tartin) the 0erver
%efore startin) the 0erver. one should first start the $bject Re)istr. and leave it runnin)
in the back)round. $ne performs this b usin) the command'
rmire)istr H
It takes a second or so for the $bject Re)istr to start runnin) and to start listenin) on its
socket. If one is usin) a script. then one should pro)ram a pause after startin) the $bject
Re)istr. If one is tpin) at the command line. it is unlikel that one could tpe fast
enou)h to )et ahead of the $bject Re)istr.
The 0erver should then be started= and. like the $bject Re)istr. left runnin) in the
back)round. The example 0erver is started usin) the command'
java 4ello0erver H
The 0erver will take a few seconds to start runnin). and to construct and re)ister remote
objects. 0o one should wait a few seconds before runnin) an #lients. "rintin) a suitable
messa)e. as in the example 0erver. is helpful for determinin) when the 0erver is read.
Runnin) a #lient
Th #lient is run like an other java pro)ram. The example #lient is executed usin)'
java 4ello#lient
2or this to run it is necessar for the 4ello#lient. 4elloInterface and 4elloI0tub classes
be available on the client machine. In particular. the 4ello#lient.class.
4elloInterface.class and 4elloI0tub.class files must be in one of the directories specified
in the #B&00"&T4.
In theor. it should be possible for the client to download the necessar class files from
the server without the need for these classes to be on the client machine. In practice. this
is ver difficult to accomplish because classes can use other classes in other packa)es.
and these other packa)es are determined b the #B&00"&T4 which is locall defined on
each machine. More sophisticated (and more complex) remote method invocation
mechanisms (such as #$R%&) can achieve this. but simpler mechanisms like RMI
cannot (at least not et).
0ecurit
$ne of the most common problems one encounters with RMI is a failure due to securit
constraints. This section )ives a ver brief introduction to the Java securit model as it
relates to RMI. 2or a more complete treatment. one should read the documentation for the
Java 0ecuritMana)er and "olic classes and their related classes. 9ote that this section
assumes that one is usin) Java (.* or later. 0ome of the statements are not true for earlier
versions.
& Java pro)ram ma specif a securit mana)er that determines its securit polic. &
pro)ram will not have an securit mana)er unless one is specified. $ne sets the securit
polic b constructin) a 0ecuritMana)er object and callin) the set0ecuritMana)er
method of the 0stem class. #ertain operations re-uire that there be a securit mana)er.
2or example. RMI will download a 0eriali8able class from another machine onl if there
is a securit mana)er and the securit mana)er permits the downloadin) of the class from
that machine. The RMI0ecuritMana)er class defines an example of a securit mana)er
that normall permits such downloads.
4owever. man Java installations have instituted securit policies that are more
restrictive than the default. There are )ood reasons for institutin) such policies. and one
should not override them carelessl. In particular. if our Java virtual machine alread
has a securit mana)er and if this securit mana)er does not allow the
set0ecuritMana)er method to be invoked. then ou will not be able to chan)e securit
policies other than as allowed b the existin) securit mana)er. This is the case for
applets runnin) in a browser. In order to protect the client from potentiall dan)erous
applets. the securit mana)er of applets does not allow man operations. includin)
readin) and writin) local files. as well as chan)in) the securit mana)er.
The rest of this section discusses some was that can be used for overridin) securit
policies that prevent RMI from functionin) properl.
The 0ecuritMana)er class has a lar)e number of methods whose name be)ins with
check. 2or example. check#onnect (0trin) host. int port). If a check method returns. then
the permission was )ranted. 2or example. if a call to check#onnect returns normall. then
the current securit polic allows the pro)ram to establish a socket connection to the
server socket at the specified host and port. If the current securit polic does not allow
one to connect to this host and port. then the call throws an exception. This usuall causes
our pro)ram to terminate with a messa)e such as'
java.securit.&ccess#ontrol;xception' access denied
(java.net.0ocket"ermission (*J.C.C.('(CDD connect.resolve)
The messa)e above would occur when an RMI server or client was not allowed to
connect to the RMI re)istr runnin) on the same machine as the server or client.
&s discussed above. one sets the securit polic b passin) an object of tpe
0ecuritMana)er to the set0ecuritMana)er method of the 0stem class. There are
several was to modif the securit polic of a pro)ram. The simplest techni-ue is to
define a subclass of 0ecuritMana)er and to call 0stem.set0ecuritMana)er on an object
of this subclass. In the definition of this subclass. ou should override those check
methods for which ou want a different polic. 2or example. if ou find that our ,4ello.
7orld5, pro)ram refuses to connect to the re)istr. then ou should override the
check#onnect methods. There are two check#onnect methods. The first was discussed
above. and the second check#onnect method has a third parameter that specifies the
securit context of the re-uest.
The followin) code illustrates how to do this'
0stem.set0ecuritMana)er (new RMI0ecuritMana)er() >
public void check#onnect (0trin) host. int port) >@
public void check#onnect (0trin) host. int port. $bject context) >@
@)=
The code above uses an anonmous inner class. 0uch a class is convenient when the class
will onl be used to construct an object in one place. as in this example. $f course. one
could also define the subclass of RMI0ecuritMana)er in the usual wa.
Kefinin) and installin) a securit mana)er was the ori)inal techni-ue for specifin) a
securit polic in Java. :nfortunatel. it is ver difficult to desi)n such a class so that it
does not leave an securit holes. 2or this reason. a new techni-ue was introduced in
Java (.*. which is backward compatible with the old techni-ue. In the default securit
mana)er. all check methods (except check"ermission) are implemented b callin) the
check"ermission method. The tpe of permission bein) checked is specified b the
parameter of tpe "ermission passed to the check"ermission method. 2or example. the
check#onnect method calls check"ermission with a 0ocket"ermission object. The default
implementation of check"ermission is to call the check"ermission method of the
&ccess#ontroller class. This method checks whether the specified permission is implied
b a list of )ranted permissions. The "ermissions class is used for maintainin) lists of
)ranted permissions and for checkin) whether a particular permission has been )ranted.
This is the mechanism whereb the securit mana)er checks permissions. but it does not
explain how one specifies or chan)es the securit polic. 2or this purpose there is et
another class. named "olic. Bike 0ecuritMana)er. each pro)ram has a current securit
polic that can be obtained b callin) "olic.)et"olic(). and one can set the current
securit polic usin) "olic.set"olic. if one has permission to do so. The securit polic
is tpicall specified b a polic confi)uration file (or ,polic file, for short) which is
read when the pro)ram starts and an time that a re-uest is made to refresh the securit
polic. The polic file defines the permissions contained in a "olic object. It is not
inaccurate to think of the polic file a kind of seriali8ation of a "olic object (except that
a polic file is intended to be readable b humans as well as b machines). &s an
example. the followin) will )rant all permissions of an kind to code residin) in the RMI
director on the #' drive'
)rant code%ase ,file'#'/RMI/!, >
permission java.securit.&ll"ermission= @=
The default securit mana)er uses a polic that is defined in a collection of polic files.
2or the locations of these files see the documentation of the polictool pro)ram. If one
wishes to )rant additional permissions. then one can specif them in a polic file and then
re-uest that the be loaded usin) options such as the followin)'
java !Kjava.securit.mana)er !Kjava.securit.policApolic!file M#lass
%oth of the ,!K, options specif sstem properties. The first sstem propert has the
same effect as executin) the followin) statement as the first statement in our pro)ram'
0stem.set0ecuritMana)er (new 0ecuritMana)er())=
The second sstem propert above causes the specified polic!file (which is specified
with a :RB) to be added to the other polic files when definin) the entire securit polic.
The polictool can be used to construct the polic file. but one can also use an text
editor.
&s if this wasn3t alread complicated enou)h. there is et another wa to deal with the
problem of downloadin) 0eriali8able classes. The command!line option
!Kjava.rmi.server.codebaseAcode!base specifies a location from which 0eriali8able
classes ma be downloaded. $f course. our securit mana)er must reco)ni8e this sstem
propert. and not all of them will do so. 2urthermore. as mentioned earlier. this is onl
necessar if ou actuall need to download 0eriali8able classes.
Runnin) the client and server
$ur example was extremel simple. More complex sstems. however. mi)ht contain
interfaces that chan)e. or whose implementation chan)es. To run this article3s examples.
both the client and server will have a cop of the classfiles. but more advanced sstems
mi)ht share the code of the server on a webserver. for downloadin) as re-uired. If our
sstems do this. don3t for)et to set the sstem propert java.rmi.server.codebase to the
webserver director in which our classes are stored5
6ou can download all the source and class files to)ether as a sin)le LI" file. :npack the
files into a director. and then perform the followin) steps.
(. 0tart the rmire)istr
To start the re)istr. 7indows users should do the followin) (assumin) that our
javaMbin director is in the current path)'!
start rmire)istr
To start the re)istr. :nix users should do the followin)'!
rmire)istr H
*. #ompile the server
#ompile the server. and use the rmic tool to create stub files.
+. 0tart the server
2rom the director in which the classes are located. tpe the followin)'!
java "ower0ervice0erver
N. 0tart the client
6ou can run the client locall. or from a different machine. In either case. ou3ll
need to specif the hostname of the machine where ou are runnin) the server. If
ou3re runnin) it locall. use localhost as the hostname.
java "ower0ervice#lient localhost
TI" ! If ou runnin) the client or server with JKO(.*. then ou3ll need to
chan)e the securit settin)s. 6ou3ll need to specif a securit polic file
(a sample is included with the source code and classes) when ou run
the client and server.
The followin) chan)es should be made when runnin) the server
java !Kjava.securit.policAjava.polic "ower0ervice0erver
The followin) chan)es should be made when runnin) the client
java !Kjava.securit.policAjava.polic "ower0ervice#lient localhost

Das könnte Ihnen auch gefallen