我可以通过JNI从Node.js调用Java吗?如何?

Kay*_*ale 44 java java-native-interface node.js

我可以通过JNI从Node.js调用Java 吗?有什么例子吗?

Dav*_*son 107

你应该尝试node-java npm模块,它是一个写得很好的JNI包装器.

node-jave似乎(但)没有被广泛采用,但是玩它,我对它的直接性和强大性印象深刻.

它很简单:

var list = java.newInstanceSync("java.util.ArrayList");
list.addSync("item1");
list.addSync("item2");
console.log(list.getSync(1)); // prints "item2"
Run Code Online (Sandbox Code Playgroud)

您可以使用嵌入式JVM执行任何操作 - 创建对象,调用方法,访问字段等.

Node和Java之间存在轻微的阻抗不匹配,因此如果您要与复杂的东西进行交互,我建议您使用Java编写大部分交互,并在Node/Java屏障中展示更简单的接口.它只是简化调试方式.

---戴夫

ps,RealWorldUseCase(tm):我在一个在多个浏览器客户端和基于Java的服务之间具有相当复杂(和意大利面条编码)协议的地方工作.我写了一个非常好的测试工具,它使用jsdom来托管N个模拟浏览器,并使用node-java作为Java服务代码的包装器.无论是在客户端的JS中还是在服务的Java中,都要简化传输接口,因此无论何时发送消息,我都会捕获它并将其粘贴到队列中以便将概率传递到预期的目标(即,我虚拟化了网络).通过这种方式,我可以运行与Java服务交互的多个客户端的全面模拟,并在单个进程内运行整个事务而无需任何有线通信.然后我可以做一些有趣的事情,比如故意重新排序消息传递,以确保代码能够适应时间错误.当发现错误时,我记录了消息排序,并可以重现它们以重现错误.哦,整个事情设置并运行一个非常复杂的场景,有几千行记录,每次运行不到1秒.花了2周时间.好玩的东西.

真实世界的使用案例#2:硒INPROC -一个包装SeleniumRC JAR文件提供了一个节点接口到浏览器自动化测试W/A模块,而无需尚未运行其他本地主机服务.


Daf*_*aff 9

这看起来很棘手.Node.JS在Google Chrome JavaScript引擎V8上运行.您需要做的是创建一个V8 C++绑定(v8 c ++ Crash Course显示一个示例),它启动JVM并执行所有JNI处理.

我认为让JavaServer和Node.js通过网络进行通信可能会更好(有人写了一个使用RabbitMQ for Java/Node.js基于消息的通信的例子).在这里,JSON将是一种出色的数据交换格式(如果您信任您的Java服务器生成适当的JSON,您可以在Node中eval()它).

  • 这取决于你想做什么.JNI的方法将是很多工作和调试的地狱(仅JNI已经很痛苦,而且V8会更糟 - > C++ - > JNI - > Java). (4认同)
  • 我在考虑更多的实际消息传递队列,例如ZeroMQ(http://zero.mq/) (2认同)
  • Dave的回答[这里](http://stackoverflow.com/a/9352818/3196753)(> 60 upvotes)应该是接受的答案,它讲的是node-java npm模块. (2认同)

Yog*_*wal 5

可以通过child_process进行通信.

生成一个新进程并执行一个Main类.此主类将输出返回到控制台.所以数据可用于节点的stdout data事件.

var cmd    = require('child_process').spawn('java', ['Main']);

cmd.stdout.on('data', function (data) {
  console.log('stdout: ' + data); // This will print string returned by Main class.
});
Run Code Online (Sandbox Code Playgroud)