RMI ClassNotFoundException:仅适用于java 1.4.2客户端的java.RMI.server.RemoteObjectInvocationHandler

时间:2013-12-08 18:24:01

标签: java rmi

我正在研究Java RMI应用程序。

对于使用java 7的客户端,可以正确运行所有内容。

但对于使用java 1.4.2的客户端。

服务器在带有java 7的Windows XP上运行。

服务界面:

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(我用这个运行服务)
  4. RmiServer.bat:

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

    在客户端,我有“Client”文件夹,在此我有:

    1. RMIClient.jar
    2. 的java.policy
    3. stub_folder / rmiserver /(这是一个包含ServiceImplementation_Stub.class的文件夹)
    4. lib /(这是一个包含RmiServer.jar的文件夹)
    5. RMIClient.bat(我用这个运行客户端)
    6. 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
      

      感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

您正在运行没有存根的1.5+服务器,这会导致动态存根以动态代理和RemoteObjectInvocationHandler的形式使用,而1.4客户端在JRE中没有RemoteObjectInvocationHandler类

您需要运行'rmic'并在服务器和客户端正确部署存根。您尚未在服务器和客户端正确部署存根类。它甚至没有在服务器上找到。它应该在两端的JAR文件中,而不是在CLASSPATH未知的某些怪异目录中。

或更新客户端以使用当前的JDK。 1.4是过去多年的生命结束。