2016-07-02 5 views
0

동적 클래스 로딩 메커니즘이 어떻게 작동하는지 약간 혼란 스럽습니다. 나는 아래의 클래스를 구현하고 그들이 모두 같은 src 디렉토리에있을 때 나는 ide, server 및 client에서 그것들을 시작한다. 그러나 내가 그들을 분리하면 나는 그것을 작동하게 만들 수 없다. RMI의 작동 방식을 설명하는 많은 안내서가 있지만 파일을 분리하고 실행하는 방법을 설명하지는 않습니다.자바에서의 RMI 동적 클래스 로딩, localhost에서 코드를 분리하고 시작하는 방법?

그래서 내가 한 것 : 모든 클래스를 컴파일하고 해당 .class 파일을 가져 왔습니다.

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

이 숙제 질문 서버가 클라이언트 로컬 호스트에있는 것 모두 일 : 그럼 별도의 클라이언트, 서버 및 일반 클래스에 폴더 및 하위 폴더를 만들었습니다. 어쨌든, 다음 갔지 내가 그것을 클래스

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 

그래서 일을 내가 얻을 그것을 할 방법

을 찾을 수 없습니다

$ java -Djava.rmi.server.codebase=/home/myuser/rmitest/common/ Server . 

와 서버 시작? 내 수업의 분리가 맞습니까? 어떻게 서버와 클라이언트를 시작해야합니까? 감사. 아래에서

내 클래스를 찾을 수 :

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); 
     } 
} 

답변

0

모든 클래스를 컴파일하고 해당 .class 파일을 가져 왔습니다. 그런 다음 폴더와 하위 폴더를 만들어 클라이언트, 서버 및 공용 클래스를 분리했습니다.

잘못된 것입니다. 소스 코드의 해당 패키지 문과 함께 소스 코드 수준에서 먼저 분리해야합니다. 그런 다음 컴파일하십시오. 그런 다음 컴파일러는 .class 파일을 패키지 계층에 해당하는 디렉토리 구조에 넣습니다.

NB ServerImpl은 일반적인 클래스가 아닙니다. 서버에서만 사용됩니다.

+0

감사합니다. 그래서 'import common.NotifyEventInterface' (모든 필요한 클래스)를 Client에 추가하고 함께 컴파일하면 괜찮습니까? 이제는 작동하지만 클라이언트, 서버 및 공용 파일 용 jar 파일을 만들면 제대로 작동하지 않습니다. 'java -cp common/Common.jar : server/Server.jar -Djava.rmi.server.codebase = file : /path/rmitest/common/Common.jar "-jar server/Server.jar 어떻게해야합니까? – user3717434

+0

죄송 합니다만, infact 같은 src에서 패키지를 컴파일 할 때 ide에서 작동하지만 명령 행에서 실행하면 작동하지 않습니다. (jar없이 jar로 할 수 없습니다. 아직 작동) – user3717434

+0

죄송합니다, 잘못된 파일 이름입니다. 지금 작동합니다. – user3717434