当前位置: 首页 > 知识库问答 >
问题:

如何使用classloader将类文件从服务器加载到客户端

杭曦
2023-03-14

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

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

共有1个答案

於鸿羲
2023-03-14

我找到了解决方案,希望在这里与大家分享。首先,此作业是网络类加载。可以在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,在客户端使用Socketchannel。(实际上,您必须先知道如何通过套接字连接两台远程计算机。)

向客户端发送类文件字节的服务器端代码:

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

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

 类似资料:
  • 问题内容: 我正在尝试从服务器向客户端发送文件,即服务器请求的客户端。客户端指定中的文件,然后将其发送到服务器,服务器将文件大小添加到文件中,然后将其返回给客户端。 客户端向其管道添加具有正确文件大小的新文件。 服务器使用上下文和所需文件创建一个新文件,并尝试发送该文件,但是从不读取该字节。 我在这里做错了什么? 记录 客户 FileRequestHandler.java FileChunkReq

  • 问题内容: 我正在尝试找到一种方法,将不同文件类型的文件从服务器发送到客户端。 我在服务器上有以下代码将文件放入字节数组: 然后,我将fileData作为字符串发送给客户端。这对于txt文件效果很好,但是当涉及到图像时,我发现尽管它可以很好地创建包含数据的文件,但图像无法打开。 我不确定我是否正在按照正确的方式进行操作。谢谢您的帮助。 问题答案: 如果要读取/写入二进制数据,则应使用字节流(Inp

  • 我试图从客户端复制文件到服务器,在Java,像这样: 客户: 服务器: 当我跑步时,我得到: 但什么都没发生。这是我第一次使用客户机服务器,我不确定自己出了什么问题。 请帮帮忙。谢谢你。

  • 问题内容: 这个问题困扰了我一段时间。我必须在我的Java应用程序中加载几个文件,到目前为止,我工作的唯一方式是这样的: 但这是丑陋和可怕的。有一阵子我以为我在做这个工作: 但这由于某种原因不再起作用(我必须做些更改并且没有注意到。它返回null。 我应该使用getResource()而不是getSystemResource()(如果这样),为什么getSystemResource()是静态的却不

  • 问题内容: 我设法将文件从客户端大块上传到服务器,但是现在我想实现相反的方式。不幸的是,此部分缺少官方模块页面上的文档。 我要执行以下操作: 向服务器发出流和带有文件名的“下载”事件 服务器应创建一个readstream并将其通过管道传输到客户端发出的流 当客户端到达流时,将出现一个下载弹出窗口,并询问将文件保存在何处 我不想使用简单的文件超链接的原因令人困惑:服务器上的文件已加密并重命名,因此我

  • 问题内容: 我对Ajax和JSON足够熟悉,可以发送请求并解析JSON请求。理想情况下,我希望收到多个响应以定期更新进度条。这样客户可以得到积极的反馈。 我听说过JSON流,但没有找到有关如何实现此功能的好资源。有谁知道好的资源或如何做到这一点? 问题答案: JSON只是通过HTTP协议传输的另一种数据格式(例如文本,html,pdf等)。您可能指的是cometd。 这使您可以打开持久连接,并将数