2017-01-31 5 views
-1

Ich habe nio channel, dass mein Client eine Klassendatei vom Server-Computer laden soll. Sie sind im selben IP-Bereich. Ich habe zwei Schnittstellen, die auf Server und Client-Maschine üblich sind. Und eine Klasse, die die Schnittstelle auf dem Serverrechner implementiert. Ich verwende den folgenden Code auf meinem Client-Computer, aber ClassNotFoundException wird angezeigt, wenn ich es ausführe.Wie Klassenladeprogramm verwendet wird, um Klassendatei vom Server zum Client zu laden

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

Was ist der vollständige Prozess des Ladens von Klassen in diesem Fall?

+0

Ich habe eine Frage. Wo ist deine Frage? : D – Matt

+0

Sie sollen hier eine Frage stellen. Sie können zwar Ihre eigene Frage beantworten, aber zuerst müssen Sie eine Frage stellen –

+0

Java's eingebaute RMI benutzt diese Verteilung von Klassen, so dass es funktionieren kann, aber ich würde warnen, dass es unwahrscheinlich ist, eine gute Idee zu sein. Ich schlage vor, Daten so weit wie möglich zu verteilen anstatt Code. –

Antwort

1

Ich habe die Lösung gefunden und möchte sie hier teilen. Erstens ist dieser Job das Laden von Netzwerkklassen. Es kann in Javadoc mit diesem Namen gefunden werden. Eigentlich gibt es keine Möglichkeit, eine Klassendatei von Remote-Computern zu laden, indem Sie den folgenden Code:

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

Auch wenn Sie die URL ändern, um „http“, während es kein HTTP-Protokoll zwischen zwei getrennten Computern. Nun, lasst uns den richtigen Weg beginnen.

Angenommen, Sie haben zwei Computer mit 192.168.10.1 (Server) und 192.168.10.2 (Client) IPs. Es gibt eine Klassendatei, die der Client nicht von der Serverfestplatte auf seine Festplatte kopieren sollte. Also, beginnen Sie zuerst, die gleiche Schnittstelle auf beiden JVM (Server und Client) zu definieren. mit dem gleichen Paket wie die folgende Schnittstelle:

package org.counter.biz; 

public interface ProcessAlgorithm { 

    int doProcess() ; 

} 

So ist diese Schnittstelle auf Server und Client üblich. Zweitens sollte Ihre Hauptklasse auf dem Server definiert und implementiert die Schnittstelle:

package org.counter.biz; 

public class Action implements ProcessAlgorithm { 

    @Override 
    public int doProcess() { 

     /* something to do */ 

    } 
} 

Und schließlich die Klassendatei sollte an den Client auf Buchse oder Buchse Kanal gesendet werden. Hier verwende ich Socketchannel auf meinem Server und Socket auf meinem Client. (Eigentlich muss man wissen, wie sich zwei Remote-Computer über die Buchse zum Anschluss zuerst.)

Server-Side-Code der Bytes der Klassendatei an den Client zu senden:

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

    } 

Es gibt viel Möglichkeit, eine Datei zu senden über Steckdose. Es ist mein Code und seine Richtigkeit wurde untersucht.

Client-Seite, um die Datei zu empfangen und in eine Klasse zu ändern, die nicht auf der Festplatte des Clients gespeichert ist.

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; 

    } 

} 

Dann:

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

Dann können Sie die Klasse wie diese

verwenden
iAction.doProcess(); 

Wenn es irgendeine Frage, ich bin hier zu beantworten. :)

Verwandte Themen