我可以通过 JNI 从Node.js调用Java吗?有没有例子?
答案 0 :(得分:104)
你应该试试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"
您可以使用嵌入式JVM执行任何操作 - 创建对象,调用方法,访问字段等。
Node和Java之间存在轻微的阻抗不匹配,因此如果您要与复杂的东西进行交互,我建议您使用Java编写大部分交互,并在Node / Java屏障中展示更简单的接口。它只是让这种方式更容易调试。
---戴夫
p.s。,RealWorldUseCase(tm):我在一个在多个浏览器客户端和基于Java的服务之间具有相当复杂(和意大利面条编码)协议的地方工作。我编写了一个非常好的测试工具,使用jsdom来托管N个模拟浏览器,并使用node-java作为Java服务代码的包装器。无论是在客户端的JS中还是在服务的Java中,都要简化传输接口,因此无论何时发送消息,我都会捕获它并将其粘贴到队列中以便将概率传递到预期的目标(即,我虚拟化了网络)。通过这种方式,我可以运行与Java服务交互的多个客户端的全面模拟,并在单个进程内运行整个事务而无需任何有线通信。然后我可以做一些有趣的事情,比如故意重新排序消息传递,以确保代码能够适应时间错误。当发现错误时,我记录了消息排序,并可以重现它们以重现错误。哦,整个事情设置并运行一个非常复杂的场景,有几千行记录,每次运行不到1秒。花了2周时间。好玩的东西。
RealWorld用例#2:selenium-inproc - 一个包装SeleniumRC JAR文件的模块,为浏览器自动化测试提供节点接口w / Selenium,而无需运行另一个本地主机服务。
答案 1 :(得分:8)
看起来很棘手。 Node.JS在Google Chrome JavaScript引擎V8上运行。您需要做的是创建一个V8 C ++绑定(v8 c++ Crash Course显示一个示例),它启动JVM并执行所有JNI处理。
我认为让JavaServer和Node.js通过网络进行通信可能会更好(有人为基于Java / Node.js消息的通信写了一个example for using RabbitMQ)。在这里,JSON将是一种出色的数据交换格式(如果您信任您的Java服务器生成正确的JSON,您可以在Node中eval())。
答案 2 :(得分: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.
});
答案 3 :(得分:0)
我不知道Node.js的所有细节,但我假设你提到的JNI实际上是Java Native Interface。一个人只能使用Java中的JNI,所以如果你还没有使用Java,那么从JNI访问Java是没有意义的。
这似乎是错误的方法,你需要搜索Node.js doco的集成章节......
答案 4 :(得分:0)
我想知道它是否有可能。但即使有可能,我想也很难实现,我确信没有人这样做过。
如何使用named pipe在进程之间进行通信(java和node.js)?
答案 5 :(得分:0)
我认为您正在寻找的是用作桥梁的原生扩展。虽然我没有你所说的例子,但我确实有一个关于如何使用Node.JS调用C ++扩展的例子