简体   繁体   中英

RMI UnmarshalException

I'm currently developing a system that loads classes via rmi. This system uses a classloader that communicates with the server in order to get the classes. The code is as follows.

Server:

import rocks.squareRock;

import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class Server extends UnicastRemoteObject
        implements RemInterface {

    public Server() throws RemoteException {
        super();
    }

    public static void main(String argv[]) {
        try {
            Server serv = new Server();
            Naming.rebind("RockServer", serv);
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }

    public Class<?> getRockClass(String type) {
        if (type.equals("squareRock"))
            return squareRock.class;
        else
            return null;
    }
}

Client:

import rocks.Rock;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;

public class Client {
    RemInterface reminterface = null;
    RockLoader rl = null;

    public Client() {
        String strName = "rmi://127.0.0.1/RockServer";
        try {
            reminterface = (RemInterface) Naming.lookup(strName);
            rl = new RockLoader(reminterface);
        } catch (RemoteException e) {
            e.printStackTrace();
        } catch (NotBoundException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }

        loadRock("squareRock");

    }

    public Rock loadRock(String rock) {
        try {
            return (Rock) rl.loadClass(rock, false).newInstance();
        } catch (Throwable t) {
            return null;
        }
    }
}

Interface:

public interface RemInterface {
    public Class<?> getRockClass(String type) throws RemoteException;
}

RockLoader:

import java.io.Serializable;

public class RockLoader extends ClassLoader implements Serializable {

    private RemInterface reminterface = null;

    public RockLoader(RemInterface reminterface) {
        super();
        this.reminterface = reminterface;
    }

    @Override
    protected synchronized Class<?> loadClass(String className, boolean resolve)
            throws ClassNotFoundException {
        try {
            return reminterface.getRockClass(className);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}

The error I'm getting with this is (client-side):

java.rmi.UnmarshalException: error unmarshalling return; nested exception is: 
java.lang.ClassNotFoundException: SquareRock

This confuses me, as I'm not unmarshalling a SquareRock instance, but a Class. The only thought I have is that my classloader might be wrong.

It doesn't matter whether it's a Class or an object. The receiving JVM must have that class in its classpath, unless you are using the RMI codebase feature. What you are doing is basically trying to implement the codebase feature yourself. You can't do that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM