2013-12-08 46 views
0

我正在研究Java RMI應用程序。RMI ClassNotFoundException:java.rmi.server.RemoteObjectInvocationHandler僅適用於java 1.4.2客戶端

對於使用java 7的客戶端,正確運行所有內容。

但是對於使用java 1.4.2的客戶端。

服務器上的Windows XP運行的Java 7

服務接口:

package rmiserver; 
import java.rmi.*; 

public interface ServiceInterface extends Remote { 

    public static final int port=1099; 
    public String getString(Integer n) throws RemoteException; 

} 

服務實現:

package rmiserver; 
import java.rmi.*; 
import java.rmi.RemoteException; 
import java.rmi.server.UnicastRemoteObject; 



public class ServiceImplementation extends UnicastRemoteObject implements ServiceInterface{ 


    public ServiceImplementation() throws RemoteException { 
     try { 
     } catch (Exception e) { 
      System.out.println("Error:" + e.toString()); 
     } 
    } 

    public String getString(Integer n) throws RemoteException {   
     return n.toString();   
    } 

    public static void main(String[] args) { // Por ej. en el main del servidor RMI 
     int port = ServiceInterface.port; 
     System.setSecurityManager(new RMISecurityManager()); 
     try { 
      java.rmi.registry.LocateRegistry.createRegistry(port); 
     } catch (Exception e) { 
      System.out.println(e.toString() + "Rmiregistry OK."); 
     } 
     try { 
      ServiceImplementation service = new ServiceImplementation(); 
      String machine = "//192.168.1.3" + ":" + port; 
      String name_service = "/serviceString"; 
      String serviceRemoto = machine + name_service; 
      Naming.rebind(serviceRemoto, service); 
      System.out.println("....OK....."); 
     } catch (Exception e) { 
      System.out.println("Error: " + e.toString()); 
     } 
    } 


} 

客戶:

package rmiclient; 

import java.rmi.Naming; 
import java.rmi.RMISecurityManager; 
import rmiserver.ServiceInterface; 

public class RMIClient { 


    public static void main(String[] args) { 
     try { 
      ServiceInterface service; 
      String name_service = "/serviceString"; 
      System.setSecurityManager(new RMISecurityManager()); 
      int port = ServiceInterface.port; 
      String machine = "192.168.1.3"; 
      service = (ServiceInterface) Naming.lookup("rmi://" + machine + ":" +port + name_service); 
      System.out.println("OUTPUT: "+service.getString(new Integer(23))); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

    } 
} 

在客戶端和我有以下的java.policy在服務器上:

grant { 
permission java.security.AllPermission; 
}; 

在服務器端,我有「服務」文件夾,這下我有:

  1. RmiServer.jar
  2. 的java.policy
  3. RmiServer.bat(我運行此服務)

RmiServer.bat:

java -classpath RmiServer.jar -Djava.rmi.server.codebase=file:RmiServer.jar -Djava.security.policy=java.policy -jar RmiServer.jar 

在客戶端我有 「客戶」 文件夾,這下我有:

  1. RMIClient.jar
  2. 的Java。政策
  3. stub_folder/rmiserver /(它是一個包含ServiceImplementation_Stub.class的文件夾)
  4. LIB /(它是包含RmiServer.jar的文件夾)
  5. RMIClient.bat(I運行客戶端與此)

RMIClient.bat:

java -classpath lib -Djava.rmi.server.codebase=file:lib -Djava.security.policy=java.policy -jar RMIClient.jar 

我生成的存根如下:

rmic -classpath RmiServer.jar -d stub_folder rmiserver.ServiceImplementation 

我有以下錯誤在Java 1.4.2運行客戶端:

java.rmi.UnmarshalException: error unmarshalling return; nested exception is: 
     java.lang.ClassNotFoundException: java.rmi.server.RemoteObjectInvocation 
Handler 
     at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source) 
     at java.rmi.Naming.lookup(Unknown Source) 
     at rmiclient.RMIClient.main(RMIClient.java:17) 
Caused by: java.lang.ClassNotFoundException: java.rmi.server.RemoteObjectInvocat 
ionHandler 
     at java.net.URLClassLoader$1.run(Unknown Source) 
     at java.security.AccessController.doPrivileged(Native Method) 
     at java.net.URLClassLoader.findClass(Unknown Source) 
     at java.lang.ClassLoader.loadClass(Unknown Source) 
     at java.lang.ClassLoader.loadClass(Unknown Source) 
     at java.lang.ClassLoader.loadClassInternal(Unknown Source) 
     at java.lang.Class.forName0(Native Method) 
     at java.lang.Class.forName(Unknown Source) 
     at sun.rmi.server.LoaderHandler.loadClass(Unknown Source) 
     at sun.rmi.server.LoaderHandler.loadClass(Unknown Source) 
     at java.rmi.server.RMIClassLoader$2.loadClass(Unknown Source) 
     at java.rmi.server.RMIClassLoader.loadClass(Unknown Source) 
     at sun.rmi.server.MarshalInputStream.resolveClass(Unknown Source) 
     at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source) 
     at java.io.ObjectInputStream.readClassDesc(Unknown Source) 
     at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source) 
     at java.io.ObjectInputStream.readObject0(Unknown Source) 
     at java.io.ObjectInputStream.defaultReadFields(Unknown Source) 
     at java.io.ObjectInputStream.readSerialData(Unknown Source) 
     at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source) 
     at java.io.ObjectInputStream.readObject0(Unknown Source) 
     at java.io.ObjectInputStream.readObject(Unknown Source) 
     ... 3 more 

感謝您的幫助。

回答

2

您正在運行一個沒有存根的1.5+服務器,這會導致使用動態存根(以動態代理和RemoteObjectInvocationHandler的形式)以及一個1.4客戶端,其中沒有RemoteObjectInvocationHandler類JRE。

您需要運行「rmic」並在服務器和客戶端正確部署存根。您尚未在服務器和客戶端正確部署存根類。它甚至沒有在服務器上找到。它應該位於兩端的JAR文件中,而不是位於CLASSPATH未知的某個怪異目錄中。

或更新客戶端以使用當前的JDK。 1.4是多少年過去的結束。

+0

Java客戶端無法更新1.4.2,因爲應用程序將被僅支持該Java版本的遺留系統使用。對不起,要問這樣一個愚蠢的東西,但在jar中添加存根的最好方法是什麼? –

+1

將任何其他.class文件放入jar中的方式相同。 – EJP

+0

用rmic -v1.1創建存根和骨架,並添加符合RmiServer.jar中目錄結構的類 在兩個運行指示「-Djava.rmi.server.codebase = file:F:/RmiServer.jar」 但仍然給出了同樣的錯誤。 對不起,但我錯過了什麼? –