2

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

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

我的实施考虑是典型的

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

有没有“正确的方法”?如果没有,我有什么选择,每种选择的优缺点是什么?

(人们实际上已经做过并且可以提供真实反馈的东西会很棒!)

4

11 回答 11

3

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

  • 真的很容易实现
  • 从其他 JVM 调用真的很容易
  • 支持远程机器
  • jconsole 允许您在不编写客户端的情况下手动测试您的 MBean

缺点:

  • 客户端必须在 JVM 上(我认为)
  • 对于更复杂的数据结构和交互来说不是很好。例如,我认为 MBean 不能返回对另一个 MBean 的引用。它将序列化并返回一个副本。
于 2008-12-15T16:07:40.077 回答
3

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

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

XML-RPC:现在这并不时髦,但它简单而有效。有Java 库以及大多数其他语言的库。

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

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

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

于 2008-12-15T19:03:30.770 回答
2

由于您的调用者不是 Java 应用程序,并且您已经预见到网络调用者,RMI-IIOP (CORBA)可能是一种选择。虽然它绝对不容易实现,但它的优势是成为一个被广泛认可的标准。

于 2008-12-15T16:25:31.290 回答
2

由于您的调用者不是基于 JVM 的,因此这是与 JVM 的进程间通信问题。我想到的选项是:

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

选项 3 IMO 是执行此操作的最“Java”方式,并且是最复杂/最容易出错的。选项 2 丑陋但简单 选项 1 比较简单(java 部分),否则没问题。

于 2008-12-15T16:30:22.060 回答
1

为了便于使用,我会使用Spring Remoting。如果你已经在你的项目中使用 Spring,那是没有道理的。如果你不是......好吧,无论如何你应该看看。

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

于 2008-12-15T16:33:08.780 回答
1

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

于 2009-10-08T22:55:52.343 回答
0

JNI(Java Native Interface)允许从 C 或 C++ 访问 java 代码。

于 2008-12-15T16:18:44.563 回答
0

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

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

于 2008-12-15T16:23:48.593 回答
0

您想要的是 Java 本机接口 (JNI),尽管它可能存在困难。没有其他同等技术可以如此容易实施。

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

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

于 2008-12-15T16:38:03.573 回答
0

如果另一个进程将在同一台机器上并且操作系统是否符合 POSIX(不是 Windows),另一个需要考虑的替代方法是命名管道。

外部进程将操作作为字符串或其他约定的字节编码写入命名管道,而 Java 应用程序正在从管道读取,解析传入的操作并针对您的对象执行它们。

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

于 2008-12-15T21:32:42.997 回答
0

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

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

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

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

于 2009-01-27T19:54:29.757 回答