【问题标题】:How to use classloader to load class file from server to client如何使用类加载器将类文件从服务器加载到客户端
【发布时间】:2017-06-17 05:25:00
【问题描述】:

我有一个 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();

这种情况下类加载的完整过程是什么?

【问题讨论】:

  • 我有一个问题。你的问题在哪里? :D
  • 你应该在这里问一个问题。您确实可以回答自己的问题,但首先您需要提出一个问题
  • Java 的内置 RMI 使用这种类分布,因此它可以工作,但我警告说这不太可能是一个好主意。我建议尽可能多地分发数据而不是代码。
  • 莎拉,你已经设法在 Stackoverflow 上提出了 4 个问题,并且都获得了反对票。你真的应该去参观stackoverflow.com/tour
  • @Peter Lawrey : 我用过 RMI,但如你所知,如果你想用 socket 打开一个通道,你不应该再用 RMI 打开另一个通道。

标签: java sockets classloader urlclassloader


【解决方案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 协议。那么让我们从正确的方式开始吧。

假设您有两台计算机,其 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。 (其实你得先知道如何通过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();

如果有任何问题,我会在这里回答。 :)

【讨论】:

  • 你好,谢谢,clientSocketmain() 方法中是什么
猜你喜欢
  • 1970-01-01
  • 2012-11-26
  • 2014-12-22
  • 1970-01-01
  • 1970-01-01
  • 2020-05-23
  • 2022-01-13
  • 1970-01-01
  • 2016-02-08
相关资源
最近更新 更多