2008-12-15 65 views
2

我有一个非常简单的Java类,它使用输入验证有效地装饰了一个Map,其中使用了显而易见的void set()和String get()方法。如何从JVM外部调用对象中的方法?

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

我的实现考虑是典型

  • 性能
  • 便于实施和维护(简单?)
  • 可靠性的
  • 灵活性(即我可以从远程设备呼叫等)

有没有“正确的方法?如果不是,我的选择是什么,每个选项有哪些赞成/反对?

(东西的人实际上已经完成,可以提供真实的反馈意见将是巨大的!)

回答

3

好的。现在再试一次,我知道客户端不是Java。既然你想进程外访问和远程机器访问,我不认为JNI是你想要的,因为这是严格的过程中(和一个麻烦)。以下是一些其他选项:

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

XML-RPC:这是不是如髋关节,这些天,但它是简单而有效的。有Java libraries以及大多数其他语言的图书馆。

CORBA:如上所述,CORBA是一种选择,但它非常复杂,专家越来越难以得到。

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

网络服务:我认为这会更复杂,但是您可以使用JAX-WS将对象公开为Web服务。 NetBeans拥有用于构建Web服务的相当不错的工具,但这可能是矫枉过正的。

3

你们会从其他基于JVM的系统调用,或者是客户端语言任意?如果您从另一个JVM调用,最简单的方法之一是通过JMX将对象作为MBean公开。规范Hello World MBean显示为here。好处有:

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

缺点:

  • 客户有权为O n一个JVM(我认为)
  • 对于更复杂的数据结构和交互不太好。例如,我不认为MBean可以返回对另一个MBean的引用。它会序列化并返回一份副本。
+0

感谢,呼叫者我心目中是不是另一个JVM,但很好的答案,我认为我的 – Brabster 2008-12-15 16:26:03

0

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

+0

类是在运行的JVM;我想从外面调用课堂上的方法。我认为JNI是一种使Java本地代码可用的方法,所以我不认为这是我正在寻找的... – Brabster 2008-12-15 16:24:25

0

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

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

2

由于您的呼叫者不是Java应用程序,并且您已经预见到网络呼叫者,因此可能会提供RMI-IIOP (CORBA)选项。尽管实施起来并不容易,但它具有被广泛认可的标准的优点。

2

由于您的来电者是不是JVM为基础的,这是JVM进程间通信的问题。我想到的选项是:

  1. 通信通过套接字:使你的JVM听传入连接和来电发送命令
  2. 通信使用共享文件(主叫方写入文件,JVM投票和更新)
  3. 使用JNI,在调用者进程内启动JVM,然后使用RMI/MBeans与第一个(“服务器”)JVM进行通信。来电者将有权访问使用JNI的结果

选项3 IMO是这样做的最“Java”方式,并且是最复杂/容易出错的方式。 选项2很难看但很简单 选项1非常容易(java部分),否则就ok了。

1

为了方便使用,我会用Spring Remoting。如果你已经在你的项目中使用Spring,那是毫不费力的。如果你没有...好,你应该看看。

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

0

你想要的是Java本地接口(JNI),尽管它可能出现的困难。没有其他同等技术可以很容易实现。

至于在前面的答案的评论提到的,JNI是用于从Java调用本机代码优化,但它也可以用于一点点的工作相反。在您的本地代码中,您需要实现JNI入口点 - 类似于SetMapPointer() - 然后在构建Map之后从Java代码中调用该函数。 SetMapPointer()的实现应该将Java对象指针保存在某个可访问位置,然后本地代码可以根据需要在其上调用Java方法。

你需要确保这种情况发生在正确的顺序(即本地代码不会尝试访问地图,它已经建成并传递给本机代码之前),但是这不应该是一个特别难题。

0

另一种方法来考虑,如果其他进程将是在同一台机器上,并且操作系统是POSIX兼容的(而不是Windows)的命名管道。

当Java应用程序正在从管道中读取数据时,外部进程将字符串或其他一致同意的字节编码写入命名管道,解析传入操作并针对对象执行它们。

这是一个你想用套接字连接,只是代替一个SocketInputStream你会从附加到命名管道一个FileInputStream来读的同样的策略。

0

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

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

的文档也很出色。我不会说这是特别容易拿起,但可能比CORBA更容易。

否则,另一种选择,我不认为已经提到是由思科,现在捐赠给Apache的开发出新的中间件/ RPC框架,称为Etch。尽管如此,它还是很新的,而且文档很少。

0

BeanShell的是壳状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(); 

这个小工具更容易做远程Java调用JNI比或RMI曾经拥有。

更多,开始在:http://www.beanshell.org/manual/remotemode.html