编写运行RMI程序
(文中内容直接引自java.sun.com上的权威文档,为了保持原貌,没有对E文进行翻译)
(本文有待于进一步完整)
(bigleo 2006.10.27)
一、用到的JDK中的工具:
javac
RMIC
java (其中的-D参数的用法)
rmiregistry
说明:
rmic DESCRIPTION
The rmic compiler generates stub and skeleton class files (JRMP protocol) and stub and tie class files
(IIOP protocol) for remote objects. These classes files are generated from compiled Java programming
language classes that are remote object implementation classes. A remote implementation class is a class
that implements the interface java.rmi.Remote. The class names in the rmic command must be for classes
that have been compiled successfully with the javac command and must be fully package qualified. For
example, running rmic on the class file name HelloImpl as shown here:
rmic hello.HelloImpl
rmiregistry DESCRIPTION
The rmiregistry command creates and starts a remote object registry on the specified port on the current
host. If port is omitted, the registry is started on port 1099. The rmiregistry command produces no
output and is typically run in the background. For example:
start rmiregistry
A remote object registry is a bootstrap naming service that is used by RMI servers on the same host to
bind remote objects to names. Clients on local and remote hosts can then look up remote objects and make
remote method invocations.
The registry is typically used to locate the first remote object on which an application needs to invoke
methods. That object in turn will provide application-specific support for finding other objects.
The methods of the java.rmi.registry.LocateRegistry class are used to get a registry operating on the
local host or local host and port.
The URL-based methods of the java.rmi.Naming class operate on a registry and can be used to look up a
remote object on any host, and on the local host: bind a simple (string) name to a remote object, rebind
a new name to a remote object (overriding the old binding), unbind a remote object, and list the URLs
bound in the registry.
二、codebase:
(详细内容参考:http://java.sun.com/j2se/1.4.2/docs/guide/rmi/codebase.html#section4)
1、codebase是什么?
A codebase can be defined as a source, or a place, from which to load classes into a Java virtual
machine. For example, if you invited a new friend over for dinner, you would need to give that friend
directions to the place where you lived, so that he or she could locate your house. Similarly, you can
think of a codebase as the directions that you give to a JVM, so it can find your [potentially remote]
classes.
You can think of your CLASSPATH as a "local codebase", because it is the list of places on disk from
which you load local classes. When loading classes from a local disk-based source, your CLASSPATH
variable is consulted. Your CLASSPATH can be set to take either relative or absolute path names to
directories and/or archives of class files. So just as CLASSPATH is a kind of "local codebase", the
codebase used by applets and remote objects can be thought of as a "remote codebase".
2、在RMI中如何使用codebase
(1)Using RMI, applications can create remote objects that accept method calls from clients in other
JVMs. In order for a client to call methods on a remote object, the client must have a way to
communicate with the remote object. Rather than having to program the client to speak the remote
object's protocol, RMI uses special classes called stubs that can be downloaded to the client that are
used to communicate with (make method calls on) the remote object. The java.rmi.server.codebase property
value represents one or more URL locations from which these stubs (and any classes needed by the stubs)
can be downloaded.
Like applets, the classes needed to execute remote method calls can be downloaded from "file:///" URLs,
but like applets, a "file:///" URL generally requires that the client and the server reside on the same
physical host, unless the file system referred to by the URL is made available using some other
protocol, such as NFS.
(2)注意事项
Note1: Before you start the rmiregistry, you must make sure that the shell or window in which you will
run the registry either has no CLASSPATH set or has a CLASSPATH that does not include the path to any
classes that you want downloaded to your client, including the stubs for your remote object
implementation classes.
If you start the rmiregistry, and it can find your stub classes in its CLASSPATH, it will ignore the
server's java.rmi.server.codebase property, and as a result, your client(s) will not be able to download
the stub code for your remote object. For an explanation of how code downloading works in RMI, please
take a look at the tutorial on Dynamic code downloading using RMI.
Note2: When the codebase property value is set to the URL of a directory, the value must be terminated
by a "/".
Note3:注意客户端policy文件的设置,参看下面的两个例子
用本地文件的方式javaLocal.policy,此方式下要注意要充许相应的文件可以读取,下面文件中由permission
java.io.FilePermission "D:\\CH8\\Server\\-", "read";来完成。
grant {
};
用HTTP的方式javaHttp.policy
grant {
};
策略文件可以用policytool工具完成。详细的使用方式在JDK DOC文档中有。
FilePermission
A java.io.FilePermission represents access to a file or directory. A FilePermission consists of a pathname and a set of actions valid for that pathname.
Pathname is the pathname of the file or directory granted the specified actions. A pathname that ends in
A pathname consisting of a single "*" indicates all the files in the current directory, while a pathname
The actions to be granted are passed to the constructor in a string containing a list of zero or more comma-separated keywords. The possible keywords are "read", "write", "execute", and "delete". Their meaning is defined as follows:
read Permission to read.
write Permission to write (which includes permission to create).
execute Permission to execute. Allows Runtime.exec to be called. Corresponds to
SecurityManager.checkExec.
delete Permission to delete. Allows File.delete to be called. Corresponds to
SecurityManager.checkDelete.
The actions string is converted to lowercase before processing.
Be careful when granting FilePermissions. Think about the implications of granting read and especially write access to various files and directories. The "<<ALL FILES>>" permission with write action is especially dangerous. This grants permission to write to the entire file system. One thing this effectively allows is replacement of the system binary, including the JVM runtime environment.
Note: code can always read a file from the same directory it's in (or a subdirectory of that directory);
it does not need explicit permission to do so.
三、实际的例子:
(1)从HTTP网站下载的方式。
启动rmiregistry:
set classpath=c:\
start RMIregistry
说明:classpath一定设到一个没有class文件的目录。
启动服务器:
D:\CH8\Server>java
Djava.security.policy=java.policy
说明:不要忘了你指定的网站一定要是可以访问,并存在接口文件的class文件和stub文件。
启动客户端:
D:\CH8\Client>java
Djava.security.policy=javaHttp.policy RMIClient1 127.0.0.1
(2)在本地硬盘下载stub文件的方式。
启动rmiregistry:
set classpath=c:\
start RMIregistry
说明:classpath一定设到一个没有class文件的目录。
启动服务器:
D:\CH8\Server>java
RemoteServer
启动客户端:
D:\CH8\Client>java -Djava.rmi.server.codebase=file:/d:\\ch8\\server/
Djava.security.policy=javaLocal.policy RMIClient1 127.0.0.1
说明:policy文件中要允许对相关目录下文件的读取。
(3)当然还有一个更直接的方式,直接把stub文件copy到客户端所在目录,也可以。