RMI編程簡(jiǎn)單教程(來(lái)自JBuilder) - BeanSoft‘s Java Resea...
Project:
RMI: A Simple RMI Application
項(xiàng)目:RMI:一個(gè)簡(jiǎn)單的RMI應(yīng)用程序
Author: JBuilder Team
作者:JBuilder工作組
Company: borland.com
公司:borland.com
Description:
This sample will guide you through the steps to create a simple RMI application
描述:這個(gè)示例將會(huì)教你建立一個(gè)簡(jiǎn)單的RMI應(yīng)用程序的步驟.
Steps to creation of an RMI application:
一個(gè)RMI應(yīng)用程序的創(chuàng)建步驟
The short version
精簡(jiǎn)版
1) Create an interface. (in this case, the interface is SimpleRMIInterface.java).1) 創(chuàng)建一個(gè)接口.(在這個(gè)例子中,接口是SimpleRMIInterface.java).2) Create a class that implements the interface. (in this case, SimpleRMIImpl.java).2) 創(chuàng)建一個(gè)實(shí)現(xiàn)這個(gè)接口的類.(在這里,是SimpleRMIImpl.java).3) Create a server that creates an instance of this class.3) 創(chuàng)建一個(gè)建立了一個(gè)這個(gè)類的示例的服務(wù)器.4) Create a client that connects to the server object using Naming.lookup().4) 創(chuàng)建一個(gè)使用Naming.lookup()連接到服務(wù)器對(duì)象的客戶.5) Set the compile options on the RMI implementation file.5) 設(shè)置RMI實(shí)現(xiàn)文件的編譯選項(xiàng).6) Compile these classes.6) 編譯這些類.7) Start the RMI registry.7) 打開(kāi)RMI注冊(cè).8) Start the server class.8) 運(yùn)行服務(wù)器類.9) Run the client program.9) 運(yùn)行客戶程序.
The long version
詳細(xì)版
Create an interface.
建立一個(gè)接口.
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.
這個(gè)例子創(chuàng)建的接口是
SimpleRMIInterface.java.它僅僅含有一個(gè)方法;這個(gè)方法不需要參數(shù)并且返回一個(gè)java.util.Date類型的對(duì)象.注意這個(gè)接口中的兩件事: 1)它繼承自java.rmi.Remote接口(所有使用RMI的接口必須這樣做). 2)這個(gè)方法拋出一個(gè)java.rim.RemoteException(一個(gè)遠(yuǎn)程對(duì)象接口中的每個(gè)方法都必須在它的"throws"子句中列入這個(gè)異常;這個(gè)異常是所有能夠拋出的RMI異常的超類.參看JDK最終文檔(在java.rmi部分)獲得可以拋出的異常的完整列表.
Create a class that implements the interface.
建立一個(gè)實(shí)現(xiàn)上面接口的類.
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.
在本例中,可以在
SimpleRMIImpl.java中找到這個(gè)實(shí)現(xiàn).這個(gè)類必須繼承自java.rmi.UnicastRemoteObject,并且必須實(shí)現(xiàn)你在步驟1中創(chuàng)建的接口.在我得例子中,唯一需要實(shí)現(xiàn)的方法是getDate(),它返回系統(tǒng)上當(dāng)前的日期和時(shí)間.注意接口中的構(gòu)造方法: 1)對(duì)super()的調(diào)用. 2)對(duì)Naming.rebind(name, this)的調(diào)用.這個(gè)調(diào)用通知RMI注冊(cè)器這個(gè)以"字符串名字"為名字的對(duì)象可以使用了.除此之外,這個(gè)對(duì)象只不過(guò)實(shí)現(xiàn)了接口中定義的所有方法.
Create a server that creates an instance of the "impl" class.
創(chuàng)建一個(gè)創(chuàng)建了一個(gè)"impl"類實(shí)例的服務(wù)器.
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://<your server here>/SimpleRMIImpl instance". (and in fact, this is how the client connects to it in step 4).
在這個(gè)例子中,服務(wù)器類是
SimpleRMIServer.java.在這種情況下,服務(wù)器相當(dāng)簡(jiǎn)單.它做了2件事: 1)安裝一個(gè)新的RMISecurityManage(注意RMI使用了一個(gè)和applet所使用的安全管理器不同的管理器). 2)創(chuàng)建SimpleRMIImpl類的實(shí)例,給它一個(gè)名字"SimpleRMIImpl instance".SimpleRMIImpl對(duì)象使用RMI注冊(cè)器實(shí)現(xiàn)注冊(cè).代碼運(yùn)行之后,這個(gè)對(duì)象以"rmi://<your server here>/SimpleRMIImpl instance"的形式對(duì)遠(yuǎn)程客戶可用.(實(shí)際上,這就是步驟4中客戶如何連接到此對(duì)象)
Create a client that connects to the server object using Naming.lookup().
創(chuàng)建一個(gè)使用Naming.lookup()連接到服務(wù)器對(duì)象的客戶.
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.
在這個(gè)例子中,客戶類是
Set the compile options on the RMI implementation file.
設(shè)置RMI實(shí)現(xiàn)文件的編譯選項(xiàng).
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.
在集成開(kāi)發(fā)環(huán)境中,在瀏覽面板中右擊文件SimpleRMIImpl.java,選擇"Java source properties"(Java源代碼屬性).在屬性對(duì)話框中,選中"Generate RMI stub / skeleton."(創(chuàng)建RMI存根 / 框架)并且點(diǎn)擊OK按鈕. Compile these classes.
編譯這些類.
JDK 1.2 specific: make sure that the JRE Security policy is
setup for RMI.
JDK 1.2細(xì)節(jié):確保JRE的安全策略已經(jīng)
為RMI設(shè)置好.
Start the RMI registry.
運(yùn)行RMI注冊(cè)器.
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.
好了.在這一點(diǎn)你已經(jīng)開(kāi)發(fā)完畢;你已經(jīng)建立了運(yùn)行這個(gè)例子所需的所有代碼.現(xiàn)在你正在安裝環(huán)境從而你能運(yùn)行它.rmiregistry是一個(gè)來(lái)自于JDK 1.1最終版的程序;你可以在你的JDK安裝的"bin"目錄下找到它.在JBuilder內(nèi),選中 Tools | RMIRegistry.當(dāng)你第二次打開(kāi)工具菜單時(shí),你將注意到在這個(gè)菜單選項(xiàng)附近有一個(gè)復(fù)選框.這是你的注冊(cè)器正在運(yùn)行的線索.再次選中它將會(huì)關(guān)閉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下從命令行運(yùn)行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.
這將會(huì)使RMI注冊(cè)器在它自己的DOS窗口下運(yùn)行.RMI注冊(cè)器必須在你運(yùn)行你自己的服務(wù)器之前運(yùn)行.
Start your RMI server program.
運(yùn)行你自己的RMI服務(wù)器程序.
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".
從項(xiàng)目中運(yùn)行SimpleRMIServer.這將使服務(wù)器運(yùn)行.正如我們?cè)缧r(shí)候討論的,這個(gè)服務(wù)器于是建立一個(gè)SimpleRMIImpl的示例并且使它被RMI服務(wù)器命名為"SimpleRMIImpl instance".
Run your client program.
運(yùn)行你的客戶程序.
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.
運(yùn)行SimpleRMIClient.這個(gè)程序?qū)?huì)向RMI注冊(cè)器詢問(wèn)一個(gè)"SimpleRMIImpl instance"的引用.在它獲得這個(gè)引用之后,客戶就能調(diào)用SimpleRMIInterface中定義的任意方法,就像這個(gè)對(duì)象是一個(gè)本地對(duì)象一樣.
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應(yīng)用程序被創(chuàng)建之后,你可能想把客戶程序從服務(wù)器發(fā)布出去.為了實(shí)現(xiàn)這個(gè)目的,你可以使用Deployment Wizard(發(fā)布向?qū)?來(lái)為客戶文件和服務(wù)器文件建立分開(kāi)的目錄.
Create a directory for the client - create a directory in any location of your liking and let us name it RMIClient
為客戶建立一個(gè)目錄 - 在你喜歡的任意位置創(chuàng)建一個(gè)目錄,讓我們把它命名為RMIClient Create a directory for the server - let us name it RMIServer
為服務(wù)器建立一個(gè)目錄 - 讓我們把它命名為RMIServer 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 com\borland\samples\rmi\simple directory under the output root directory into the com\borland\samples\rmi\simple under your client directory, RMIClient.
設(shè)置客戶發(fā)布:啟動(dòng)Deployment Wizard(發(fā)布向?qū)?,在Wizards(向?qū)?菜單下,并且設(shè)置Delivery Options(傳送選項(xiàng))為‘No Archive‘(不存檔).從文件列表中選擇SimpleRMIClient.java,SimpleRMIInterface.java和SimpleRMIImppl_Stub.java.設(shè)置Archive Output Path(存檔輸出路徑)為客戶目錄.如果SimpleRMIImpl_Stub.java在發(fā)布向?qū)У奈募斜碇袥](méi)有出現(xiàn),那么你也可以人工的將它從位于輸出根目錄下的com\borland\samples\rmi\simple子目錄下復(fù)制到你的客戶目錄RMIClient下的com\borland\samples\rmi\simple子目錄. 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 com\borland\samples\rmi\simple directory under the output root directory into the com\borland\samples\rmi\simple directory under your server directory, RMIServer.
設(shè)置服務(wù)器發(fā)布:重復(fù)上一步驟但是選擇這些文件: SimpleRMIServer.java, SimpleRMIInterface.java, SimpleRMIImpl.java, SimpleRMIImpl_Skel.java, 以及 SimpleRMIImpl_Stub.java.將這些文件放到你的服務(wù)器目錄,即我們已經(jīng)命名為RMIServer的目錄.如果SimpleRMIImpl_Stub.java和SimpleRMIImpl_Skel.java在發(fā)布向?qū)У奈募斜碇袥](méi)有出現(xiàn),那么你也可以人工的將它從位于輸出根目錄下的com\borland\samples\rmi\simple子目錄下復(fù)制到你的服務(wù)器目錄RMIServer下的com\borland\samples\rmi\simple子目錄.
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.
現(xiàn)在,一旦你設(shè)置分離了服務(wù)器和客戶,與服務(wù)器相比較,客戶可以在一個(gè)不同的計(jì)算機(jī)上運(yùn)行.如果你看一下SimpleRMIClient.java,你將注意到客戶程序僅僅使用一個(gè)是計(jì)算機(jī)名字的參數(shù),如果沒(méi)有提供這個(gè)參數(shù),它的默認(rèn)值是本地計(jì)算機(jī)的名字.下面的說(shuō)明顯示了如何在當(dāng)前計(jì)算機(jī)上運(yùn)行服務(wù)器程序,同時(shí)在另一臺(tái)通過(guò)TCP/IP和本機(jī)連接起來(lái)的計(jì)算機(jī)上運(yùn)行客戶程序.
Copy the client directory to a different machine that has either JBuilder or JDK 1.1 (or above) installed properly to run java application.
復(fù)制客戶目錄到一臺(tái)已經(jīng)正確的安裝了JBuilder或者JDK1.1(或以上)能夠運(yùn)行java應(yīng)用程序的不同的機(jī)器. Start the rmiregistry, as described above, on the current machine
啟動(dòng)rmiregistry,像在上面描述過(guò)的那樣在當(dāng)前計(jì)算機(jī)上 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
啟動(dòng)服務(wù)器程序:打開(kāi)DOS窗口,改變目錄到你的服務(wù)器目錄,RMIServer.運(yùn)行[jbuilder安裝目錄](méi)\setvars [jbuilder安裝目錄](méi).這將設(shè)置運(yùn)行Java的環(huán)境變量.運(yùn)行java com.borland.samples.rmi.simple.SimpleRMIServer.java 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].
在客戶程序上啟動(dòng)客戶.來(lái)到客戶機(jī),打開(kāi)DOS窗口,改變目錄到客戶目錄,然后鍵入java com.borland.samples.rmi.simple.SimpleRMIClient [服務(wù)器主機(jī)名].
附錄: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使用的模型更加嚴(yán)格.JDK 1.2包含了增強(qiáng)的指紋安全,需要代碼被同意授于特定的許可來(lái)進(jìn)行某些操作.
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使用套接字來(lái)進(jìn)行進(jìn)程間的,然而如果RMI應(yīng)用程序使用RMISecurityManager,那么你需要更改安全策略,從而使應(yīng)用程序被允許通過(guò)套接字接受和連接到其它的RMI應(yīng)用程序.
The easiest way to setup the security mechanism to enable RMI is to modify the java.policy file under the java\jre\lib\security directory in your JBuilder installation directory. Open it with a text editor and modify the line that says:
最簡(jiǎn)單的使安全機(jī)制使RMI可用的設(shè)置方法是更改在JBuiler安裝目錄下的java\jre\lib\security目錄下的文件java.policy.用一個(gè)文本編輯器打開(kāi)它并且更改如下行:
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.
這將允許你在本地計(jì)算機(jī)上運(yùn)行服務(wù)器應(yīng)用程序和客戶應(yīng)用程序.
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.
請(qǐng)注意文件java.policy控制了全部的Java安全策略.另一種選擇是你可以建立一個(gè)名字為".java.policy"的文件放在用戶的家目錄下.在Windows平臺(tái)上,用戶的家目錄代表性的翻譯為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的安全的更徹底的解釋,請(qǐng)去看看極好的
JavaSoft站點(diǎn)的教程.
補(bǔ)充說(shuō)明:
此目錄下的程序沒(méi)有包名,并且RMI的端口也被更改為5000,詳情請(qǐng)參看源代碼.
建立一個(gè)沒(méi)有名字,只有擴(kuò)展名的文件可以使用Windows的edit.com,這里用來(lái)建立.java.policy.或者使用位于JDK安裝目錄下的policytool.exe來(lái)保存文件為此名稱,或者是除了notepad.exe以外的其它文本編輯器,甚至你可以使用一個(gè)Java程序來(lái)建立,最簡(jiǎn)單的就是使用COPY CON FILE的DOS命令.
如果你只想在此處使用安全策略,那么可以建立一個(gè)為.policy為擴(kuò)展名的文件,例如java.policy.在文件中寫(xiě)入如下內(nèi)容[此處允許所有主機(jī)]:
grant
{
permission java.net.SocketPermission "*:1024-", "listen, accept, connect";
};
然后使用這個(gè)策略文件的命令是:
運(yùn)行客戶程序:
java -Djava.security.policy=java.policy SimpleRMIClient
運(yùn)行服務(wù)器程序:
java -Djava.security.policy=java.policy SimpleRMIServer
使RMI運(yùn)行在5000端口的命令:rmiregistry 5000
使用rmic.exe可以得到存根文件,此處的用法是:rmic SimpleRMIImpl
如果生成JDK1.2的存根類,這樣:rmi -V1.2 SimpleRMIImpl
RMI的命名規(guī)則:
無(wú)后綴 [例如A] 遠(yuǎn)程接口
Impl后綴 [例如AImpl] 實(shí)現(xiàn)接口的服務(wù)器類
Server后綴[例如AServer] 創(chuàng)建服務(wù)器對(duì)象的服務(wù)器程序
Client后綴[例如AClient] 調(diào)用遠(yuǎn)程方法的客戶程序
_Stub后綴 [例如A_Stub] rmic程序自動(dòng)生成的代碼存根類
_Skel后綴 [例如A_Skel] rmic程序自動(dòng)生成的框架類[適用于JDK1.1]
相關(guān)的評(píng)論:
2004-12-07 13:50:48
首先 我要感謝 整蠱之王 提醒了我,我還在網(wǎng)上尋找這方面的列程,看了你的東西之后,就去JBuilder的Sample目錄下去看了看,找到了你所說(shuō)的例子。
然后按照你翻譯的就去做了,竟然失敗。查看原因:說(shuō)找不到 SimpleRMIImpl.java 這些文件,我就覺(jué)得奇怪了,明明就在目錄下怎么會(huì)找不到那?我又仔細(xì)察看了保錯(cuò)信息,發(fā)現(xiàn)他說(shuō)是在 C:\...\..\..下找不到這個(gè)文件,但是我的JBuilder是裝在D:\...\..\目錄里。于是我就用 UltraEdit(注意) 打開(kāi)這個(gè)工程的工程文件 SimpleRMI.jpx ,果然在其中發(fā)現(xiàn)了什么 C:\....\...然后修改成為我JBuilder所安裝的路徑,然后再去打開(kāi)這個(gè)工程就抱錯(cuò),說(shuō)是文檔不正確,然后我才想到 UltraEdit 打開(kāi)一個(gè)文件 時(shí)回把它Format 成 Dos 格式,于是我就用其他工具它開(kāi)那個(gè)文件再修改才成功。
這上面有兩點(diǎn)注意:一個(gè)是JBuilder的安裝目錄,一個(gè)是打開(kāi)那個(gè)工程文件的編輯器。
我寫(xiě)出這些,希望大家不要犯和我一樣的錯(cuò)誤
BeanSoft:
正確的程序的運(yùn)行方法是: 首先運(yùn)行 runRMIRegistry.bat, 這個(gè)啟動(dòng) RMI 注冊(cè)程序, 然后運(yùn)行 runServer.bat, 這個(gè)啟動(dòng)用戶編寫(xiě)的 RMI 服務(wù)器, 最后, 運(yùn)行 runClient.bat, 就可以看到返回當(dāng)前日期了.
至于 JB8 的發(fā)布向?qū)У膯?wèn)題, 我可以告訴大家一下, 好像自從 JB7 以后的版本中, 這個(gè)功能已經(jīng)合并到了 Archive Builder 中, 訪問(wèn)的菜單是 File->New->Build->Archive Builder.
選項(xiàng)都選擇默認(rèn)的, 應(yīng)該就可以打包了.