Java 如何从JVM外部调用对象中的方法?
我有一个非常简单的Java类,它通过输入验证有效地装饰了一个映射,使用了明显的void set()和String get()方法 我希望能够有效地调用这些方法并处理来自JVM外部的返回值和异常,但仍然在同一台机器上Update:我想到的调用方不是另一个JVM;谢谢@Dave Ray 我的实现考虑是典型的Java 如何从JVM外部调用对象中的方法?,java,jvm,communication,Java,Jvm,Communication,我有一个非常简单的Java类,它通过输入验证有效地装饰了一个映射,使用了明显的void set()和String get()方法 我希望能够有效地调用这些方法并处理来自JVM外部的返回值和异常,但仍然在同一台机器上Update:我想到的调用方不是另一个JVM;谢谢@Dave Ray 我的实现考虑是典型的 演出 易于实施和维护(简单性?) 可靠性 灵活性(即,我可以从远程机器等进行呼叫) 有“正确的方法”吗?如果没有,我的选择是什么,每个选择的利弊是什么 (人们实际做过并能提供真实反馈的事情会
- 演出
- 易于实施和维护(简单性?)
- 可靠性
- 灵活性(即,我可以从远程机器等进行呼叫)
(人们实际做过并能提供真实反馈的事情会很棒!)您是从另一个基于JVM的系统调用,还是客户端语言是任意的?如果您是从另一个JVM调用,最简单的方法之一是通过JMX将对象公开为MBean。显示了规范的Hello World MBean。优点是:
- 真的很容易实现吗
- 从其他JVM调用非常容易
- 支持远程机器
- jconsole允许您在不编写客户机的情况下手动测试MBean
- 客户机必须在JVM上(我认为)
- 不适合更复杂的数据结构和交互。例如,我认为一个MBean不能返回对另一个MBean的引用。它将序列化并返回一个副本
- 通过套接字通信:使JVM侦听传入的连接和调用方发送的命令
- 使用共享文件进行通信(调用方写入文件、JVM轮询和更新)
- 使用JNI,在调用者进程内启动JVM,然后使用RMI/MBean与第一个(“服务器”)JVM通信。调用方将使用JNI访问结果 选项3 IMO是最“Java”的方法,也是最复杂/最容易出错的方法。 选项2丑陋但简单
另一种方法是使用一些跨语言通信/消息传递,您的Java程序充当服务器。Corba浮现在脑海中,因为它是语言不可知论者。但可能有点重。你可以使用插座。RPC也是另一个流行词,但我在这方面没有太多经验。因为您的呼叫者不是Java应用程序,而且您已经预见到网络呼叫者,所以可能是一种选择。尽管它确实不容易实现,但它的优点是它是一个被广泛认可的标准。因为您的调用者不是基于JVM的,所以这是一个与JVM的进程间通信问题。我心目中的选择是:
选项1相当简单(java部分),其他方面都可以。为了便于使用,我会使用。如果您已经在项目中使用了Spring,那么这是不需要动脑筋的。如果你不是。。。不管怎样,你应该看看
Spring提供了一个抽象,允许您轻松切换远程处理协议。它支持部署最广泛的协议(SOAP、Hessian、Burlap、RMI等)。如果您是从非Java代码调用的,它支持多种其他语言,已知比SOAP更高效,比CORBA更简单。您需要的是Java本机接口(JNI),尽管它可能会出现困难。没有其他同等技术能像它那样容易实现 正如前面答案的注释中所提到的,JNI针对从Java调用本机代码进行了优化,但它也可以用于相反的用途,只需做一点工作。在本机代码中,需要实现JNI入口点——类似SetMapPointer()——然后在构建映射后从Java代码调用该函数。SetMapPointer()的实现应该将Java对象指针保存在可访问的位置,然后本机代码可以根据需要在其上调用Java方法
您需要确保这是以正确的顺序发生的(即,在构建映射并将其传递给本机代码之前,本机代码不会尝试访问映射),但这应该不是一个特别困难的问题。确定。现在我知道客户机不是Java,下面是另一个尝试。由于您需要进程外访问和可能的远程机器访问,我认为JNI不是您想要的,因为这是严格意义上的进程内访问(而且非常麻烦)。以下是一些其他选项: 原始套接字:只需在Java中设置侦听器套接字并接受连接。当您获得连接时,读取请求并发送回响应。几乎每种语言都可以使用套接字,所以这是一个非常通用的解决方案。但是,您必须定义自己的编组方案、解析等 :这已经不是那么时髦了,但它简单有效。在大多数其他语言中,也有库 CORBA:如上所述,CORBA是一种选择,但它相当复杂,而且越来越难找到专家 Web服务器:在应用程序中设置嵌入式Web服务器并处理请求。我听说了一些好消息,或者你可以用这个。我已经使用后者成功地将KML文件从Java编写的模拟服务器发送到Google Earth。大多数其他语言都有用于发出HTTP请求的库。如何对数据(XML、文本等)进行编码取决于您 Web服务:我认为这会更复杂,但您可以使用它将对象公开为Web服务。NetBeans有非常好的工具来构建Web服务
i = new bsh.Interpreter();
i.set( "myapp", this ); // Provide a reference to your app
i.eval("server(7000)");
telnet localhost 7001
myapp.someMethod();