RMI编程简单教程–BeanSoft 翻译[11 1,2001,Thu]

Project Notes
项目备注


</p>

Project:

</strong>RMI: A Simple RMI Application
</font>项目:RMI:一个简单的RMI应用程序
Author: JBuilder Team
作者:JBuilder工作组
Company: borland.com
公司:borland.com
Description:
This sample will guide you through the steps to create a simple RMI application
描述:这个示例将会教你建立一个简单的RMI应用程序的步骤.

Steps to creation of an RMI application:
一个RMI应用程序的创建步骤

The short version
精简版

1) Create an interface. (in this case, the interface is SimpleRMIInterface.java).
1) 创建一个接口.(在这个例子中,接口是SimpleRMIInterface.java).
2) Create a class that implements the interface. (in this case, SimpleRMIImpl.java).
2) 创建一个实现这个接口的类.(在这里,是SimpleRMIImpl.java).
3) Create a server that creates an instance of this class.
3) 创建一个建立了一个这个类的示例的服务器.
4) Create a client that connects to the server object using Naming.lookup().
4) 创建一个使用Naming.lookup()连接到服务器对象的客户.
5) Set the compile options on the RMI implementation file.
5) 设置RMI实现文件的编译选项.
6) Compile these classes.
6) 编译这些类.
7) Start the RMI registry.
7) 打开RMI注册.
8) Start the server class.
8) 运行服务器类.
9) Run the client program.
9) 运行客户程序.

</p>

The long version

详细版

</em>

  1. Create an interface.

    建立一个接口.

    The interface created for this example is SimpleRMIInterface.java. It contains only one method; the method takes no arguments and returns an object of type java.util.Date. Note two things about this interface: 1) it extends the java.rmi.Remote interface (all interfaces used in RMI must do this). 2) the method throws a java.rmi.RemoteException (every method in a remote object’s interface must specify this exception in its "throws" clause; this exception is a superclass of all RMI exceptions that can be thrown. See the JDK 1.1 final docs (in the java.rmi section) for a complete list of exceptions that can be thrown.</p>

    这个例子创建的接口是SimpleRMIInterface.java.它仅仅含有一个方法;这个方法不需要参数并且返回一个java.util.Date类型的对象.注意这个接口中的两件事: 1)它继承自java.rmi.Remote接口(所有使用RMI的接口必须这样做). 2)这个方法抛出一个java.rim.RemoteException(一个远程对象接口中的每个方法都必须在它的"throws"子句中列入这个异常;这个异常是所有能够抛出的RMI异常的超类.参看JDK最终文档(在java.rmi部分)获得可以抛出的异常的完整列表.</p>

    </font></li>

  2. Create a class that implements the interface.

    建立一个实现上面接口的类.

    In this example, the implementation is found in SimpleRMIImpl.java. This class must extend java.rmi.UnicastRemoteObject and must implement the interface you created in step 1. In my example, the only method that needs to be implemented is getDate(), which returns the current date and time on the system. Note 2 things about the constructor: 1) the call to super(). 2) the call to Naming.rebind(name, this). This call informs the RMI registry that this object is available with the name given in "String name". Other than that, this object simply implements all the methods declared in the interface.</p>

    在本例中,可以在SimpleRMIImpl.java中找到这个实现.这个类必须继承自java.rmi.UnicastRemoteObject,并且必须实现你在步骤1中创建的接口.在我得例子中,唯一需要实现的方法是getDate(),它返回系统上当前的日期和时间.注意接口中的构造方法: 1)对super()的调用. 2)对Naming.rebind(name, this)的调用.这个调用通知RMI注册器这个以"字符串名字"为名字的对象可以使用了.除此之外,这个对象只不过实现了接口中定义的所有方法.</p>

    </font></li>

  3. Create a server that creates an instance of the "impl" class.

    创建一个创建了一个"impl"类实例的服务器.

    In this example, the server class is SimpleRMIServer.java. In this case, the server is pretty simple. It does 2 things: 1) Installs a new RMISecurityManager (Note that RMI uses a different security manager from the security manager used for applets). 2) Creates an instance of the SimpleRMIImpl class, and gives it the name "SimpleRMIImpl instance". The SimpleRMIImpl object takes care of registering the object with the RMI registry. After this code is run, the object will be available to remote clients as "rmi:///SimpleRMIImpl instance". (and in fact, this is how the client connects to it in step 4).</p>

    在这个例子中,服务器类是SimpleRMIServer.java.在这种情况下,服务器相当简单.它做了2件事: 1)安装一个新的RMISecurityManage(注意RMI使用了一个和applet所使用的安全管理器不同的管理器). 2)创建SimpleRMIImpl类的实例,给它一个名字"SimpleRMIImpl instance".SimpleRMIImpl对象使用RMI注册器实现注册.代码运行之后,这个对象以"rmi:///SimpleRMIImpl instance"的形式对远程客户可用.(实际上,这就是步骤4中客户如何连接到此对象)</p>

    </font></li>

  4. Create a client that connects to the server object using Naming.lookup().

    创建一个使用Naming.lookup()连接到服务器对象的客户.

    In this example, the client class is SimpleRMIClient.java. The client first installs a new RMI Security Manager (see previous step), then uses the static method Naming.lookup() to get a reference to the remote object. Note that the client is using the interface to hold the reference and make method calls. You should make sure you’ve created your interface before you try to build the client, or you’ll get "class not found" errors when you try to compile your client.</p>

    在这个例子中,客户类是SimpleRMIClient.java.客户首先安装一个新的RMI安全管理器(参见上一步),然后使用静态方法Naming.lookup()来得到远程对象的一个引用.注意,客户使用接口来获得引用和进行方法调用.确保在尝试建造客户类之前你已经创建了接口,否则你将在试图编译你的客户类时得到"无法找到类"的错误.</p>

    </font></li>

  5. Set the compile options on the RMI implementation file.

    设置RMI实现文件的编译选项.

    In the IDE, Right-click the SimpleRMIImpl.java file in the navigator pane and choose "Java source properties." In the properties dialog, check "Generate RMI stub / skeleton." and click OK.</p>

    在集成开发环境中,在浏览面板中右击文件SimpleRMIImpl.java,选择"Java source properties"(Java源代码属性).在属性对话框中,选中"Generate RMI stub / skeleton."(创建RMI存根 / 框架)并且点击OK按钮. </li>

  6. Compile these classes.

    编译这些类.

  7. JDK 1.2 specific: make sure that the JRE Security policy is setup for RMI.

    JDK 1.2细节:确保JRE的安全策略已经为RMI设置好.

  8. Start the RMI registry.

    运行RMI注册器.

    OK. You’re done with development at this point; you’ve built all the code you need to run this example. Now you’re setting up the environment so that you can run it. rmiregistry is a program that comes with the JDK 1.1 final; you can find it in the "bin" directory of your JDK installation. From within JBuilder, choose Tools | RMIRegistry. The next time you look at the tools menu, you will notice there is a check next to this menu option. This is your clue that the registry is running. Selecting it again will close the RMIRegistry.</p>

    好了.在这一点你已经开发完毕;你已经建立了运行这个例子所需的所有代码.现在你正在安装环境从而你能运行它.rmiregistry是一个来自于JDK 1.1最终版的程序;你可以在你的JDK安装的"bin"目录下找到它.在JBuilder内,选中 Tools | RMIRegistry.当你第二次打开工具菜单时,你将注意到在这个菜单选项附近有一个复选框.这是你的注册器正在运行的线索.再次选中它将会关闭RMIRegistry.

    Alternatively, you can start the RMIRegistry from the command line under Windows 95 or NT. To do this, type

    • setvars (jbuilder install directory)
    • start rmiregistry

    作为一种选择,你可以在Windows 95或者NT下从命令行运行RMIRegistry.要想做到这样,键入

    • setvars (jbuilder安装目录下)
    • start rmiregistry

    which will cause the RMI registry to be started in its own DOS window. The RMI registry must be started before you can start your server.

    这将会使RMI注册器在它自己的DOS窗口下运行.RMI注册器必须在你运行你自己的服务器之前运行.

  9. Start your RMI server program.

    运行你自己的RMI服务器程序.

    Run the SimpleRMIServer from the project. This starts the server running. As we discussed earlier, the server then creates an instance of SimpleRMIImpl and makes it known to the RMI server as "SimpleRMIImpl instance".</p>

    从项目中运行SimpleRMIServer.这将使服务器运行.正如我们早些时候讨论的,这个服务器于是建立一个SimpleRMIImpl的示例并且使它被RMI服务器命名为"SimpleRMIImpl instance".

    </li>

  10. Run your client program.

    运行你的客户程序.

    Run SimpleRMIClient. The program will ask the RMI registry for a reference to "SimpleRMIImpl instance". After it has this reference, the client can invoke any methods declared in the SimpleRMIInterface interface as if the object were a local object.</p>

    运行SimpleRMIClient.这个程序将会向RMI注册器询问一个"SimpleRMIImpl instance"的引用.在它获得这个引用之后,客户就能调用SimpleRMIInterface中定义的任意方法,就像这个对象是一个本地对象一样.

    </li> </ol>

    After the RMI application has been created, you probably want to deploy the client apart from the server. To accomplish this you can use the Deployment Wizard to setup separate directories for the client files and for the server files.

    在RMI应用程序被创建之后,你可能想把客户程序从服务器发布出去.为了实现这个目的,你可以使用Deployment Wizard(发布向导)来为客户文件和服务器文件建立分开的目录.

    1. Create a directory for the client – create a directory in any location of your liking and let us name it RMIClient

      为客户建立一个目录 – 在你喜欢的任意位置创建一个目录,让我们把它命名为RMIClient
    2. Create a directory for the server – let us name it RMIServer

      为服务器建立一个目录 – 让我们把它命名为RMIServer    
    3. Setup the client deployment: bring up the Deployment Wizard, under the Wizards menu, and set the Delivery Options to ‘No Archive’. Select SimpleRMIClient.java, SimpleRMIInterface.java, and SimpleRMIImpl_Stub.java from the file list. Set the Archive Output Path to the client directory. If SimpleRMIImpl_Stub.java is not show on the Deployment Wizard file list, then you can also copy it manually from the comborlandsamplesrmisimple directory under the output root directory into the comborlandsamplesrmisimple under your client directory, RMIClient.

      设置客户发布:启动Deployment Wizard(发布向导),在Wizards(向导)菜单下,并且设置Delivery Options(传送选项)为’No Archive'(不存档).从文件列表中选择SimpleRMIClient.java,SimpleRMIInterface.java和SimpleRMIImppl_Stub.java.设置Archive Output Path(存档输出路径)为客户目录.如果SimpleRMIImpl_Stub.java在发布向导的文件列表中没有出现,那么你也可以人工的将它从位于输出根目录下的comborlandsamplesrmisimple子目录下复制到你的客户目录RMIClient下的comborlandsamplesrmisimple子目录.
    4. Setup for the server deployment: repeat the previous step but select these files: SimpleRMIServer.java, SimpleRMIInterface.java, SimpleRMIImpl.java, SimpleRMIImpl_Skel.java, and SimpleRMIImpl_Stub.java. Put those files into your server directory, which we have named RMIServer. If SimpleRMIImpl_Stub.java and SimpleRMIImpl_Skel.java are not show on the Deployment Wizard file list, then you can also copy it manually from the comborlandsamplesrmisimple directory under the output root directory into the comborlandsamplesrmisimple directory under your server directory, RMIServer.

      设置服务器发布:重复上一步骤但是选择这些文件: SimpleRMIServer.java, SimpleRMIInterface.java, SimpleRMIImpl.java, SimpleRMIImpl_Skel.java, 以及 SimpleRMIImpl_Stub.java.将这些文件放到你的服务器目录,即我们已经命名为RMIServer的目录.如果SimpleRMIImpl_Stub.java和SimpleRMIImpl_Skel.java在发布向导的文件列表中没有出现,那么你也可以人工的将它从位于输出根目录下的comborlandsamplesrmisimple子目录下复制到你的服务器目录RMIServer下的comborlandsamplesrmisimple子目录.

    Now, once you have separate setup for the client and the server, the client can be run from a different computer than the server. If you take a look at SimpleRMIClient.java you will notice that the client application takes a single argument which should be a computer name, with the default of the name of the local computer, if it is not supplied. The direction below shows how to have the server running on the current machine and have client running from a different machine that are attached together through a TCP/IP network.

    现在,一旦你设置分离了服务器和客户,与服务器相比较,客户可以在一个不同的计算机上运行.如果你看一下SimpleRMIClient.java,你将注意到客户程序仅仅使用一个是计算机名字的参数,如果没有提供这个参数,它的默认值是本地计算机的名字.下面的说明显示了如何在当前计算机上运行服务器程序,同时在另一台通过TCP/IP网络和本机连接起来的计算机上运行客户程序.

    1. Copy the client directory to a different machine that has either JBuilder or JDK 1.1 (or above) installed properly to run java application.

      复制客户目录到一台已经正确的安装了JBuilder或者JDK1.1(或以上)能够运行java应用程序的不同的机器.
    2. Start the rmiregistry, as described above, on the current machine

      启动rmiregistry,像在上面描述过的那样在当前计算机上
    3. Start the server application: bring up the DOS Window and change directory to your server directory, RMIServer. Run [jbuilder_install_dir]setvars [jbuilder_install_dir]. This should setup the environment variables to run java. Run java com.borland.samples.rmi.simple.SimpleRMIServer.java

      启动服务器程序:打开DOS窗口,改变目录到你的服务器目录,RMIServer.运行[jbuilder安装目录]setvars [jbuilder安装目录].这将设置运行Java的环境变量.运行java com.borland.samples.rmi.simple.SimpleRMIServer.java
    4. Start the client on the client machine. Go to the client machine, bring up a DOS Window, change directory to the client directory, and type java com.borland.samples.rmi.simple.SimpleRMIClient [server_hostname].

      在客户程序上启动客户.来到客户机,打开DOS窗口,改变目录到客户目录,然后键入java com.borland.samples.rmi.simple.SimpleRMIClient [服务器主机名].

    </p>

    Addendum: RMI and JDK 1.2 Security

    附录:RMI和JDK1.2安全

    </strong></font>
    </a>

    附录:RMI和JDK1.2安全

    The JDK 1.2 security model is more sophisticated than the model used for JDK 1.1. JDK 1.2 contains enhancements for finer-grained security and requires code to be granted specific permissions to be allowed to perform certain operations.

    JDK 1.2的安全模型比JDK 1.1使用的模型更加严格.JDK 1.2包含了增强的指纹安全,需要代码被同意授于特定的许可来进行某些操作.

    RMI uses sockets to communicate between the processes, however if the RMI application uses the RMISecurityManager, then you need to modify the security policy so that the application is allowed to accept and connect to the other RMI application through the sockets.

    RMI使用套接字来进行进程间的
    通信,然而如果RMI应用程序使用RMISecurityManager,那么你需要更改安全策略,从而使应用程序被允许通过套接字接受和连接到其它的RMI应用程序.

    The easiest way to setup the security mechanism to enable RMI is to modify the java.policy file under the javajrelibsecurity directory in your JBuilder installation directory. Open it with a text editor and modify the line that says:

    最简单的使安全机制使RMI可用的设置方法是更改在JBuiler安装目录下的javajrelibsecurity目录下的文件java.policy.用一个文本编辑器打开它并且更改如下行:

    permission java.net.SocketPermission "localhost:1024-", "listen";

    to

    permission java.net.SocketPermission "localhost:1024-", "listen, accept, connect";

    This should allow you to run the server application and the client application on a local machine.

    这将允许你在本地计算机上运行服务器应用程序和客户应用程序.

    Please note that java.policy file controls the overall Java security policy. Alternatively you can create a file named ‘.java.policy’ that resides in the user’s home directory. On Windows platform, the user’s home directory typically translates to the Windows installation directory, while on Unix the user’s home directory refers to the actual user’s home directory.

    请注意文件java.policy控制了全部的Java安全策略.另一种选择是你可以建立一个名字为".java.policy"的文件放在用户的家目录下.在Windows平台上,用户的家目录代表性的翻译为Windows安装目录,然而在Unix上,用户的家目录是指目前用户的家目录.

    For a more thorough explanation on JDK 1.2 Security, please take a look at this excellent tutorial at JavaSoft’s site.

    要想得到JDK 1.2的安全的更彻底的解释,请去看看极好的JavaSoft站点的教程.


    补充说明:

    此目录下的程序没有包名,并且RMI的端口也被更改为5000,详情请参看源代码.

    建立一个没有名字,只有扩展名的文件可以使用Windows的edit.com,这里用来建立.java.policy.或者使用位于JDK安装目录下的policytool.exe来保存文件为此名称,或者是除了notepad.exe以外的其它文本编辑器,甚至你可以使用一个Java程序来建立,最简单的就是使用COPY CON FILE的DOS命令.

    如果你只想在此处使用安全策略,那么可以建立一个为.policy为扩展名的文件,例如java.policy.在文件中写入如下内容[此处允许所有主机]:

    grant

    {

    permission java.net.SocketPermission "*:1024-", "listen, accept, connect";

    };

    然后使用这个策略文件的命令是:

    运行客户程序:

    java -Djava.security.policy=java.policy SimpleRMIClient

    运行服务器程序:

    java -Djava.security.policy=java.policy SimpleRMIServer

    使RMI运行在5000端口的命令:rmiregistry 5000

    使用rmic.exe可以得到存根文件,此处的用法是:rmic SimpleRMIImpl

    如果生成JDK1.2的存根类,这样:rmi -V1.2 SimpleRMIImpl

    RMI的命名规则:

    </p>
    无后缀    [例如A] 远程接口
    Impl后缀  [例如AImpl] 实现接口的服务器类
    Server后缀[例如AServer] 创建服务器对象的服务器程序
    Client后缀[例如AClient] 调用远程方法的客户程序
    _Stub后缀 [例如A_Stub] rmic程序自动生成的代码存根类
    _Skel后缀 [例如A_Skel] rmic程序自动生成的框架类[适用于JDK1.1]

    相关的评论:

    评论人:匿名网友   2004-12-07 13:50:48

    首先 我要感谢  整蛊之王  提醒了我,我还在网上寻找这方面的列程,看了你的东西之后,就去JBuilder的Sample目录下去看了看,找到了你所说的例子。

    然后按照你翻译的就去做了,竟然失败。查看原因:说找不到  SimpleRMIImpl.java  这些文件,我就觉得奇怪了,明明就在目录下怎么会找不到那?我又仔细察看了保错信息,发现他说是在 C:…….下找不到这个文件,但是我的JBuilder是装在D:…..目录里。于是我就用  UltraEdit(注意)   打开这个工程的工程文件 SimpleRMI.jpx ,果然在其中发现了什么  C:…….然后修改成为我JBuilder所安装的路径,然后再去打开这个工程就抱错,说是文档不正确,然后我才想到  UltraEdit  打开一个文件 时回把它Format 成 Dos 格式,于是我就用其他工具它开那个文件再修改才成功。

    这上面有两点注意:一个是JBuilder的安装目录,一个是打开那个工程文件的编辑器。

    我写出这些,希望大家不要犯和我一样的错误

    BeanSoft:

    正确的程序的运行方法是: 首先运行 runRMIRegistry.bat, 这个启动 RMI 注册程序, 然后运行 runServer.bat, 这个启动用户编写的 RMI 服务器, 最后, 运行 runClient.bat, 就可以看到返回当前日期了.

    至于 JB8 的发布向导的问题, 我可以告诉大家一下, 好像自从 JB7 以后的版本中, 这个功能已经合并到了 Archive Builder 中, 访问的菜单是 File->New->Build->Archive Builder.

    选项都选择默认的, 应该就可以打包了.

    </div>

    </div> </p></div>

    转载请注明:WebLogic Android 博客 » RMI编程简单教程(来自JBuilder)