2017-01-31 2 views
-1

내 클라이언트가 서버 컴퓨터에서 클래스 파일을로드해야하는 nio 채널이 있습니다. 그들은 같은 IP 범위 내에 있습니다. 나는 서버와 클라이언트 컴퓨터에서 공통적 인 두 개의 인터페이스를 가지고있다. 그리고 서버 컴퓨터에서 인터페이스를 구현하는 클래스. 내 클라이언트 컴퓨터에서 다음 코드를 사용하지만이를 실행할 때 ClassNotFoundException이 나타납니다.클래스 로더를 사용하여 서버에서 클라이언트로 클래스 파일로드하는 방법

URL url = new URL("file:///E:/Computing/Master/classes/"); 
URLClassLoader ucl = new URLClassLoader(new URL[]{url}); 
Class clazz = ucl.loadClass("com.counter.controller.Action"); 
ProcessAlgorithm iAction = (ProcessAlgorithm) clazz.newInstance(); 

이 경우 클래스 로딩의 전체 과정은 무엇입니까?

+0

질문이 있습니다. 당신의 질문은 어디에 있습니까? : D – Matt

+0

여기에 질문을해야합니다. 자신의 질문에 실제로 대답 할 수 있지만 먼저 질문을해야합니다. –

+0

Java의 내장 RMI는이 클래스 배포를 사용하므로 제대로 작동 할 수 있지만 좋은 생각 일 가능성은 거의 없습니다. 코드보다는 데이터를 가능한 많이 배포하는 것이 좋습니다. –

답변

1

해결책을 찾았으며 여기에서 공유하고 싶습니다. 첫째,이 작업은 네트워크 클래스 로딩입니다. 이 이름은 javadoc에서 찾을 수 있습니다.

URL url = new URL("file:///E:/Computing/Master/classes/"); 
URLClassLoader ucl = new URLClassLoader(new URL[]{url}); 
Class clazz = ucl.loadClass("com.counter.controller.Action"); 
ProcessAlgorithm iAction = (ProcessAlgorithm) clazz.newInstance(); 

당신이 URL을 변경하더라도이 "HTTP"두 개의 별도의 컴퓨터 사이에 http 프로토콜이없는 동안 : 사실은 다음과 같은 코드를 사용하여 원격 컴퓨터에서 클래스 파일을로드 할 수있는 방법이 없습니다. 그럼 올바른 길을 시작하자.

두 대의 컴퓨터에 192.168.10.1 (서버) 및 192.168.10.2 (클라이언트) IP가 있다고 가정 해보십시오. 클라이언트가 서버 디스크에서 디스크로 복사해서는 안되는 클래스 파일이 있습니다. 먼저 JVM (서버와 클라이언트)에서 동일한 인터페이스를 정의하기 시작하십시오.

package org.counter.biz; 

public interface ProcessAlgorithm { 

    int doProcess() ; 

} 

따라서이 인터페이스는 서버 및 클라이언트에서 공통적으로 사용됩니다. 둘째, 메인 클래스는 서버에 정의 된 인터페이스를 구현해야합니다

package org.counter.biz; 

public class Action implements ProcessAlgorithm { 

    @Override 
    public int doProcess() { 

     /* something to do */ 

    } 
} 

을 마지막으로 클래스 파일은 소켓이나 소켓 채널에 클라이언트로 전송한다. 여기서는 내 서버에서 Socketchannel을 사용하고 클라이언트에서 Socketchannel을 사용합니다. (사실, 당신이 첫 번째 소켓을 통해 두 개의 원격 컴퓨터에 연결하는 방법을 알아야합니다.) 클라이언트 클래스 파일의 바이트를 보내는

서버 측 코드 :

private void sendAlgorithmFile(SocketChannel client, String filePath) throws IOException { 

     ByteBuffer buffer = ByteBuffer.allocate(8192); 
     buffer.clear(); 

     /*file path like E:\\classes\\Action.class*/ 
     Path path = Paths.get(filePath); 
     FileChannel fileChannel = FileChannel.open(path); 
     int bytes = 0; 
     int counter = 0; 


     do { 
      bytes = fileChannel.read(buffer); 
      if (bytes <= 0) 
       break; 
      counter += bytes; 
      buffer.flip(); 
      do { 
       bytes -= client.write(buffer); 
      } while (bytes > 0); 
      buffer.clear(); 
     } while (true); 


     fileChannel.close(); 

    } 

를 통해 파일을 보낼 수있는 많은 방법이있다 소켓. 그것은 내 코드이며 그 정확성을 검사했습니다.

클라이언트 측에서 파일을 받고 클라이언트 디스크에 저장되지 않은 클래스로 변경합니다. 그런 다음

package org.counter.biz; 

import java.io.IOException; 
import java.io.InputStream; 
import java.net.Socket; 

public class MyClassLoader extends ClassLoader { 

    private Socket clientChannel; 
    private int count = 0; 

    public MyClassLoader(Socket channel){ 
     this.clientChannel = channel; 
    } 

    @Override 
    protected Class findClass(String className){ 

     Class myClass = null; 

     InputStream inputStream = null; 

     try { 
      inputStream = clientChannel.getInputStream(); 
     }catch (IOException e){e.printStackTrace();} 


     byte[] bytes = new byte[8192]; 
     byte[] myBytes = null; 

     try { 
      while ((count = inputStream.read(bytes)) > 0){ 
       myBytes = new byte[count]; 
       System.arraycopy(bytes, 0, myBytes, 0, count); 
       myClass = defineClass(className, myBytes, 0, myBytes.length); 
      } 
      inputStream.close(); 
     }catch (IOException io){} 


     return myClass; 

    } 

} 

: 어떤 질문이 있으면

public class Client { 
    public static void main(String[] args) throws Exception{ 
    MyClassLoader myClassLoader = new MyClassLoader(clientSocket); 
    Class clazz = myClassLoader.findClass(null); 
    ProcessAlgorithm iAction = (ProcessAlgorithm) clazz.newInstance(); 
    } 
} 

그런 다음이

iAction.doProcess(); 

같은 클래스를 사용할 수 있습니다, 나는 대답 왔어요. :)

관련 문제