簡體   English   中英

如何使用類加載器將類文件從服務器加載到客戶端

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM