我有一个非常简单的 Java 类,它可以通过输入验证有效地装饰 Map,并使用明显的 void set() 和 String get() 方法。

我希望能够有效地调用这些方法并处理来自 JVM 外部的返回值和异常,但仍然在同一台机器上 更新:我想到的调用者不是另一个 JVM;谢谢@戴夫·雷

我的实施考虑是典型的

  • 表现
  • 易于实施和维护(简单?)
  • 可靠性
  • 灵活性(即我可以从远程机器上调用吗?)

有“正确的方式?”如果没有,我的选择是什么?每个人的支持/缺点是什么?

(人们实际做过的事情并且可以提供现实生活中的反馈那就太好了!)

有帮助吗?

解决方案

好的。现在我知道客户端不是 Java,这是另一个尝试。由于您想要进程外访问以及可能的远程计算机访问,我认为 JNI 不是您想要的,因为那是严格的进程内访问(而且很麻烦)。以下是一些其他选项:

原始套接字 :只需在 Java 中设置一个侦听器套接字并接受连接即可。当您获得连接时,读取请求并发回响应。几乎每种语言都可以使用套接字,因此这是一个非常通用的解决方案。但是,您必须定义自己的编组方案、解析等。

XML-RPC :如今这虽然不那么流行,但它简单而有效。有 Java 库 以及大多数其他语言的库。

CORBA :如上所述,CORBA 是一种选择,但它相当复杂,而且专家也越来越难找到。

网络服务器 :在您的应用程序中设置嵌入式 Web 服务器并处理请求。我听说过一些好消息 码头 或者你可以使用 一种由 Java 提供的. 。我已经成功地使用后者通过 Java 编写的模拟将 KML 文件服务器到 Google Earth。大多数其他语言都有用于发出 HTTP 请求的库。如何对数据(XML、文本等)进行编码取决于您。

网页服务 :我认为这会更复杂,但你可以使用 JAX-WS 将您的对象公开为 Web 服务。NetBeans 有非常好的工具用于构建 Web 服务,但这可能有点过头了。

其他提示

您是否会从另一个基于 JVM 的系统进行调用,或者客户端语言是任意的?如果您从另一个 JVM 调用,最简单的方法之一是通过 JMX 将对象公开为 MBean。显示了规范的 Hello World MBean 这里. 。优点是:

  • 确实很容易实施
  • 从其他 JVM 调用真的很容易
  • 支持远程机器
  • jconsole 允许您手动测试 MBean,而无需编写客户端

缺点:

  • 客户端必须位于 JVM 上(我认为)
  • 不适合更复杂的数据结构和交互。例如,我认为 MBean 不能返回对另一个 MBean 的引用。它将序列化并返回一个副本。

由于您的呼叫者不是 Java 应用程序,并且您已经预见到网络呼叫者, RMI-IIOP (CORBA) 可能是一个选择。尽管它绝对不容易实施,但它的优点是成为广泛认可的标准。

由于你的调用者不是基于JVM的,所以这是一个与JVM的进程间通信的问题。我想到的选项是:

  1. 通过套接字进行通信:让你的 JVM 监听传入的连接和调用者发送命令
  2. 使用共享文件进行通信(调用者写入文件,JVM 轮询和更新)
  3. 使用 JNI,在调用者进程内启动 JVM,然后使用 RMI/MBean 与第一个(“服务器”)JVM 进行通信。调用者将可以使用 JNI 访问结果

选项 3 IMO 是最“Java”的方式,也是最复杂/最容易出错的。选项2是丑陋的,但简单的选项1非常简单(Java Part),否则还可以。

为了方便使用,我会使用 春季远程处理. 。如果您已经在项目中使用 Spring,那么这是理所当然的。如果你不是...无论如何你应该看看。

Spring 提供了一个抽象,允许您轻松切换远程协议。它支持最广泛部署的协议(SOAP、Hessian、Burlap、RMI 等)。如果您从非 Java 代码调用, 黑森州 支持许多其他语言,比 SOAP 更高效,比 CORBA 更容易。

JNI(Java 本机接口)允许从 C 或 C++ 访问 java 代码。

我有一个 Inno Setup 脚本(安装 Java 程序),它调用一些 Java 方法来执行一些操作或检查一些条件。
我(实际上是我的前任)只是在每次调用时实例化 java.exe。显然,这成本高昂,尽管在我的情况下并不重要(我想 Windows 缓存会起作用)。

另一种方法是使用一些跨语言通信/消息传递,将 Java 程序充当服务器。我想到了 Corba,因为它与语言无关。但也许有点重。您可以使用套接字。RPC 也是另一个流行词,但我在该领域没有太多经验。

您需要的是 Java 本机接口 (JNI),尽管它可能会带来一些困难。没有其他同等技术能够如此容易实施。

正如前面答案的评论中提到的,JNI 针对从 Java 调用本机代码进行了优化,但也可以通过一些工作进行相反的用途。在您的本机代码中,您需要实现 JNI 入口点(例如 SetMapPointer()),然后在构建 Map 后从 Java 代码中调用该函数。SetMapPointer() 的实现应该将 Java 对象指针保存在可访问的地方,然后本机代码可以根据需要调用其上的 Java 方法。

您需要确保这以正确的顺序发生(即在构建并传递给本机代码之前,本机代码不会尝试访问 Map),但这不应该是一个特别困难的问题。

如果其他进程位于同一台计算机上并且操作系统符合 POSIX 标准(不是 Windows),则需要考虑的另一种选择是命名管道。

外部进程将操作(作为字符串或其他商定的字节编码)写入命名管道,同时 Java 应用程序从管道读取数据、解析传入操作并针对对象执行它们。

这与用于套接字连接的策略相同,只是您从附加到命名管道的 FileInputStream 中读取的不是 SocketInputStream。

CORBA 的替代方案是 , ,除非许可证有问题(它是GPL,但你也可以购买商业许可证)。

它几乎具有 CORBA 的所有优点,但供应商 ZeroC 提供了许多不同语言的绑定。CORBA 供应商往往只提供一两种语言绑定,然后您就会开始发现兼容性问题。

文档也很棒。我不会说它特别容易上手,但可能比 CORBA 更容易。

否则,我认为没有提到的另一个选择是 Cisco 开发的新中间件/RPC 框架,现在捐赠给 Apache,称为 蚀刻. 。但它仍然很新,而且文档也很少。

Beanshell 是一个类似 shell 的 java 解释器,可以通过网络套接字公开。基本上你可以从java中执行此操作:

i = new bsh.Interpreter();
i.set( "myapp", this );  // Provide a reference to your app
i.eval("server(7000)");

然后你可以从其他地方执行此操作:

telnet localhost 7001
myapp.someMethod();

这个小实用程序比 JNI 或 RMI 更容易执行远程 java 调用。

欲了解更多信息,请从以下位置开始: http://www.beanshell.org/manual/remotemode.html

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top