當前位置:編程學習大全網 - 源碼下載 - 運行Think In Java中的 RMI 示例可能產生的幾種異常及解決

運行Think In Java中的 RMI 示例可能產生的幾種異常及解決

下面將列出可能產生的異常,並說明解決辦法,如讀者在執行當中還遇到其他未列出的異常,可留言告知,吾將盡力而為。

首先把代碼PerfectTime和DisplayPerfectTime 中的//colossus:2005/PerfectTime改為//localhost:2005/PerfectTime ,因為colossus為機器名,所以改為localhost指向本機,不然找不到主機colossus的。

已經用命令 RMIC 生成PerfectTime_Stub.class,並且執行了命令 rmiregistry 2005

1. 執行java PerfectTime出現異常 java.security.AccessControlException: access denied (java.net.SocketPermission 127.0.0.1:2005 connect,resolve)

無法解析和連接到127.0.0.1的2005端口上,原因是在PerfectTime中設置了安全管理器<System.setSecurityManager(new RMISecurityManager());>,可是又沒有設置訪問的策略,解決辦法有四(解決這種異常的辦法同樣適用於 DisplayPerfectTime):

(1) 可以把代碼System.setSecurityManager(new RMISecurityManager());去掉,不設置安全管理器

(2) 修改JRE的安全策略文件,這就要求妳能確定執行時是用的哪個JRE,比如在Eclipse中用JDK是c:\Java\jdk1.5.0_06,相應的安全策略文件就是c:\java\jdk1.5.0_06\jre\lib\security\java.policy,如果是Applet中的java 程序就應該是在 jre 目錄中,如文件C:\Java\jre1.5.0_06\lib\security\java.policy。修改安全策略文件,在grant {},大括號中加上permission java.net.SocketPermission "localhost:2005","connect,resolve";

(3) 建立自己的策略文件,如c:\MyPolicy.policy ,內容為:grant {permission java.net.SocketPermission "localhost:2005","connect,resolve";}執行PerfectTime時用命令 java -Djava.security.policy=c:\MyPolicy.policy PerfectTime指定了安全策略文件

System.setSecurityManager (new RMISecurityManager() {

public void checkConnect (String host, int port) {}

public void checkConnect (String host, int port, Object context) {}});當然最簡單的解決方法莫過於第壹種。

2. 同樣是執行 PerfectTime 出現的異常

  java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:

java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:

java.lang.ClassNotFoundException: PerfectTime_Stub

很多人對這個問題有些莫名其妙,因為明明看到 PerfectTime_Stub 和 PerfectTime 這兩個類是在同壹個目錄中,並且classpath 也有設置當前目錄,按理既然能加載 PerfectTime 類執行,就能加載到 PerfectTime_Stub吧,為什麽還提示ClassNotFound呢?其實類 PerfectTime_Stub並非由PerfectTime執行行直接加載,而是PerfectTime在向RMI註冊時,要求 rmiregistry去加載 PerfectTime_Stub類的,理解了這壹層次上的意義就會知道其實 PerfectTime_Stub是為 rmiregistry所用的。所以解決辦法是:

(1) 在執行 rmiregistry 之前,設置classpath讓能查找到PerfectTime_Stub類,如在同壹Dos窗口中,假設 PerfectTime_Stub類是在E:\workspace\TestRMI\bin目錄中,執行過程那就是

C:\Documents and Settings\unmiset classpath=%classpath%;E:\workspace\TestRMI\bin

C:\Documents and Settings\unmirmiregistry 2005

(2) 或者在命令行中先進入到 PerfectTime_Stub類所在的目錄,然後再執行 rmiregistry (這種方法實質是與上面壹樣的,只是恰當的應用的classpath中的當前目錄 "." ),執行過程如下

C:\Documents and Settings\unmie:

E:\cd E:\workspace\TestRMI\bin

E:\workspace\TestRMI\binrmiregistry 2005參看:rmiregistry was finding the stubs in its CLASSPATH

3. 執行客戶端程序 DisplayPerfectTime 出現異常 java.security.AccessControlException: access denied (java.net.SocketPermission 127.0.0.1:1276 connect,resolve),同時在服務器端也產生異常 Exception in thread "RMI TCP Connection(6)-127.0.0.1" java.security.AccessControlException: access denied (java.net.SocketPermission 127.0.0.1:1296 accept,resolve)

直接能想到的解決辦法是把127.0.0.1:1276,127.0.0.1:1276的解析連接權限也加上,方法可取第 1 種異常所列的方法,但這個端口是隨機的。在此解析壹下這些端口的用途,2005是直接指定的供客戶端查找註冊的服務對象引用的端口,這是固定的,而上面產生的在客戶端和服務器上的1276和1296的端口,是隨機的,是在方法調用時真正的客戶端與提供服務的服務器(而非註冊服務器)之間的數據通信的端口。

為了滿足上面的端口應用,可以在安全策略文件中只加上 permission java.net.SocketPermission "localhost:*","accept,connect,resolve"; 允許在所有端口上的接受,連接,解析。再如果要訪問的IP很多,又要寫成 permission java.net.SocketPermission "*:*","accept,connect,resolve"; 方便。

4.執行客戶端程序 DisplayPerfectTime出現異常 java.rmi.UnmarshalException: Error unmarshaling return header; nested exception is:java.io.EOFException,這種異常應該比較少見,出現情況是客戶端有權限訪問服務提供端的某個端口,而服務提供端卻無權限在某個端口上或給那個客戶端提供服務造成的,解決辦法把客戶端和服務器的安全策略文件都改為能訪問任何端口就行。

  • 上一篇:推薦適合18歲以上人群的優質傳奇手遊。
  • 下一篇:如何優雅地使用iOS系統相機,相冊
  • copyright 2024編程學習大全網