在java中加载RMI动态类,如何在localhost上分离和启动代码?

时间:2016-07-02 12:46:59

标签: java rmi dynamic-class-loaders

我对动态类加载机制的工作原理有点困惑。我实现了下面的类,当它们都在同一个src目录中时,我从我的ide,服务器和客户端工作启动它们。但当我把它们分开时,我无法使其发挥作用。有很多指南解释了RMI是如何工作的,但它们没有解释我应该如何分离文件并启动它们一切都好。

所以我做了什么: 编译所有类并获得相应的.class文件。然后我创建了一个文件夹和子文件夹来分隔客户端,服务器和公共类:

home/
|-myuser/
  |--rmitest/
     |--server/ 
     |   Server.class
     |-- client/
     |   Client.class, client.policy
     |-- common/
         NotifyEventImpl.class, NotifyEventInterface.class, ServerImpl.class, ServerInterface.class

这是一个家庭作业问题服务器,客户端都可以在localhost上运行。无论如何,然后我用

启动服务器
$ java -Djava.rmi.server.codebase=/home/myuser/rmitest/common/ Server .

找不到类

Exception in thread "main" java.lang.NoClassDefFoundError: ServerImpl
    at Server.main(Server.java:15)
Caused by: java.lang.ClassNotFoundException: ServerImpl
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    ... 1 more

那么我应该怎么做才能让它发挥作用?我的分类是正确的吗?我该如何启动服务器和客户端?感谢。

在下面找到我的课程:

public interface ServerInterface extends Remote{
    void registerForCallback(NotifyEventInterface clientInterface) 
                                                throws RemoteException;
}
public class ServerImpl extends UnicastRemoteObject implements ServerInterface {
        private List<NotifyEventInterface> clients;

        public ServerImpl() throws RemoteException{
            super();
            clients = new ArrayList<NotifyEventInterface>();
        }

        public synchronized void registerForCallback(NotifyEventInterface ClientInterface) throws RemoteException{
            if(!clients.contains(ClientInterface)){
                clients.add(ClientInterface);
                System.out.println("New client registered");
            }
        }


        public void update(int value) throws RemoteException {
            doCallbacks(value);
        }

        private synchronized void doCallbacks(int value) throws RemoteException {
            System.out.println("Starting callbacks");
            Iterator i = clients.iterator();
            while(i.hasNext()){
                NotifyEventInterface client = (NotifyEventInterface) i.next();
                client.notifyEvent(value);
            }
            System.out.println("Callbacks complete");
        }

}
public class Server {
        public static void main(String[] args) {

                ServerImpl serverObj = new ServerImpl();
                int portNum = 39000;
                startRegistry(portNum);
                String registryUrl = "//:" + portNum + "/common";
                Naming.rebind(registryUrl, serverObj);
                System.out.println("Server is ready");


                while(true){
                    int val = (int) (Math.random() * 1000);
                    System.out.println("New update " + val);
                    serverObj.update(val);
                    Thread.sleep(1500);
                }

        }

        private static void startRegistry(int rmiPortNum) throws RemoteException{
            try {
                Registry registry = LocateRegistry.getRegistry(rmiPortNum);
                registry.list( );
            } catch (RemoteException ex) {
                System.out.println("RMI registry is not located at port " + rmiPortNum);
                Registry registry = LocateRegistry.createRegistry(rmiPortNum);
                System.out.println("RMI registry created at port " + rmiPortNum);
            }
        }

}
public interface NotifyEventInterface extends Remote {
    void notifyEvent(int value) throws RemoteException;
}
public class NotifyEventImpl implements NotifyEventInterface{
        public NotifyEventImpl() throws RemoteException{
            super();
        }


        @Override
        public void notifyEvent(int value) throws RemoteException {
            String returnMessage = "Update event received " + value;
            System.out.println(returnMessage);
        }
}

1 个答案:

答案 0 :(得分:0)

  

编译所有类并获得相应的.class文件。然后我创建了一个文件夹和子文件夹来分隔客户端,服务器和公共类

错误。您应该首先在源代码级别将它们与源代码中的相应包语句分开。然后编译。然后,编译器将.class文件放入与包层次结构对应的目录结构中。

NB ServerImpl不是一个普通的类。它仅供服务器使用。