2017-01-31 5 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

Встроенный в RMI 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 на своем сервере и Socket на моем клиенте. (На самом деле, вы должны знать, как соединить два удаленных компьютеров через гнездо первый.)

стороне сервера код отправки байт файла класса для клиента:

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

Если есть какие-либо вопросы, я здесь, чтобы ответить. :)