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

客户端是否必须在服务器端定义使用的类?

朱乐逸
2023-03-14

我有简单的客户端服务器应用程序使用RMI。服务器端应该生成某种PDF文件,客户端应该显示它。

当试图通过调用我自己的通用远程接口的正确方法在服务器端生成我的pdf时,ClassNotFoundExc0019被抛出在客户端。

Caused by: java.lang.ClassNotFoundException: com.itextpdf.text.ExceptionConverter (no security manager: RMI class loader disabled)

我认为,使用RMI就像使用黑盒一样——客户机调用方法并接收响应,而不知道如何完成,对双方来说唯一的公共类是远程接口。此外,我认为这将允许我将客户端所需的依赖关系缩减到最小。

客户机必须让所有服务器的库都在其类路径中才能工作吗?

编辑:另一个奇怪的事实是,在服务器端并没有任何异常。若我将服务器端项目作为依赖项添加到客户端,那个么一切正常。

共有3个答案

葛越泽
2023-03-14

好的,我找到了解决办法。看来我认为是对的——客户机不必知道服务器实现背后的内容。所有问题的关键是我们的一个类中的静态初始化块——在那里使用的资源无法解析。由于它是在静态块中,IOException不是cougt,而是生成了Error,而不是异常。将所有catches从Excetpion更改为Throwable后,服务器确实记录了正确的stacktrace和根本原因(这不包括在客户端记录的stacktrace中)。修复它只是一个次要的问题。谢谢你抽出时间!

杨凯旋
2023-03-14

如果您启用RMI类加载器并设置适当的系统属性(google for:“java.RMI.server.codebase”),那么RMI将动态地将丢失的类从服务器加载到客户机,您的问题就会消失。不需要在客户端存储和静态链接服务器库。

据我所知,RMI类加载器教程详细描述了这一切。

编辑:

我已经暗示了动态类加载的RMI特性。但我想说,在您的特殊情况下,尝试将服务器类传播到客户端可能不是一个好主意。假设有另一个类似于JMX浏览器的客户端并行运行,它可能会遇到未知类的问题。更好的方法是:在发送RMI调用结果之前,在服务器端捕获itext异常,并将其封装在另一个众所周知的异常中,例如IllegalStateException,方法是仅使用错误消息,而不使用堆栈跟踪(无论如何都应该在服务器端记录它)。

我对服务器端异常处理的想法是(伪代码):

try {
  // your server code
} catch (Throwable ex) {
  // a) log error completely including cause (stacktrace) with tools like Log4J etc.
  // b) throw new RemoteException(error.getMessage()); // without cause!
}
曹华荣
2023-03-14

这里只是猜测一下,它可能没有在服务器端正确捕获和处理ExceptionConverter,而是传播到没有定义的客户端。

 类似资料:
  • 我想在一些计算机之间建立点对点连接,这样用户就可以在没有外部服务器的情况下聊天和交换文件。我最初的想法如下: 我在服务器上制作了一个中央服务器插座,所有应用程序都可以连接到该插座。此ServerSocket跟踪已连接的套接字(客户端),并将新连接的客户端的IP和端口提供给所有其他客户端。每个客户端都会创建一个新的ServerSocket,所有客户端都可以连接到它。 换句话说:每个客户端都有一个Se

  • 问题内容: 我想在两个或更多不同的node.js应用程序服务器之间启用基于套接字的p2p通信。我正在使用socket.io处理给定服务器与其服务的Web应用程序之间的所有此类通信- 但我正在寻找的是一种服务器与服务器之间进行通信的方法。 我最初以为它像这样简单: 但是,事实证明,服务器端socket.io实现没有提供“连接”方法,仅提供了侦听方法。 为什么是这样?为什么不能将节点应用程序服务器视为

  • 问题内容: 我正在构建一个小型聊天应用程序,其中客户端A希望通过服务器B将某些东西发送到客户端C。首先,这是解决问题的正确方法吗?我能够向服务器发送数据或从服务器接收数据,但仅限于客户端。例如,如果客户端A向服务器B发送数据而客户端C向服务器B发送数据,则我可以将数据发送回服务器A和C就像回显服务器一样。但是我想要的是将来自客户端A的数据通过服务器B转发到客户端C。 以下是服务器代码: 客户端代码

  • 您好,我正在尝试从计算机中的本地客户端连接我的服务器。我有一个远程服务器正在运行。。当我从Netbeans运行代码时,一切都正常。。。当我从CMD尝试时,我得到了这个错误 Java语言com上的lang.NullPointerException。太阳企业命名。实施。SerialContext。com上的getORB(SerialContext.java:347)。太阳企业命名。实施。SerialC

  • 前面的章节介绍了所有 Redis 的重要功能组件: 数据结构、数据类型、事务、Lua 环境、事件处理、数据库、持久化, 等等, 但是我们还没有对 Redis 服务器本身做任何介绍。 不过, 服务器本身并没有多少需要介绍的新东西, 因为服务器除了维持服务器状态之外, 最重要的就是将前面介绍过的各个功能模块组合起来, 而这些功能模块在前面的章节里已经介绍过了, 所以本章将焦点放在服务器的初始化过程,

  • 但这样我就无法访问eureka仪表盘,只是使用默认配置: 在我的客户端中,同样的事情也发生了,我不能指向另一个不同于默认(localhost:8761)的eureka服务器,请参阅我的配置: 查看客户端日志,我得到了以下内容: 无论我在客户端配置什么端口或主机,都要尽量达到默认值。 重要提示:我在以下版本中使用eureka:https://mvnrepository.com/artifact/or