0

動的クラスローディングメカニズムがどのように機能するかについて、少し混乱しています。以下のクラスを実装し、それらがすべて同じ 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);
        }
}
4

1 に答える 1

0

すべてのクラスをコンパイルし、対応する .class ファイルを取得しました。次に、フォルダーとサブフォルダーを作成して、クライアント、サーバー、および共通クラスを分離しました

違う。ソース コード内の対応するパッケージ ステートメントを使用して、ソース コード レベルで最初にそれらを分離する必要があります。次にコンパイルします。コンパイラは、パッケージ階層に対応するディレクトリ構造に .class ファイルを配置します。

NBServerImplは一般的なクラスではありません。サーバーのみが使用します。

于 2016-07-03T02:22:16.103 に答える