[英]How to use classloader to load class file from server to client
我有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();
在這種情況下,類加載的完整過程是什么?
我找到了解決方案,並喜歡在這里分享。 首先,這項工作是網絡類加載。 可以在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();
即使在兩台單獨的計算機之間沒有http協議的情況下,將其URL更改為“ http”。 好吧,讓我們開始正確的方法。
假設您有兩台IP地址為192.168.10.1(服務器)和192.168.10.2(客戶端)的計算機。 有一個類文件,客戶端不應將其從服務器磁盤復制到其磁盤。 因此,首先,開始在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();
如果有任何問題,我在這里回答。 :)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.