在Node js中调用java方法

时间:2016-08-19 14:27:38

标签: javascript java node.js

我试图从节点js调用java中定义的函数。

示例:

public class A{
 public void show(){
   System.out.prntln("Invoked from Node JS");
 }
}

和节点js文件

console.log("In Node JS");
//define calling A like A a = new A();
a.show();

我可能完全错了,但我试图从节点js访问java函数。

3 个答案:

答案 0 :(得分:8)

这是一个很好的问题。一般来说,语言互操作有几种方法:

  1. 在完全独立,隔离的程序/进程中运行代码,并使用进程间通信(IPC)或其他网络协议(基于TCP的TCP或更高级别协议,如HTTP,通常使用REST-ful API,或者某种形式的RPC系统)在用不同语言编写的两个进程之间发送信息。

  2. 将一种语言“透明化”到另一种语言中(例如,使用JSweet或TeaVM转换器将Java代码转换为JavaScript代码),然后使用一种语言与原始代码一起创建单个应用程序/进程来自其他语言的转换代码(现在与最终应用程序中构建的其他代码使用相同的语言)。

  3. 使用通用的中间语言和低级“本机”接口,允许代码进行互操作。大多数语言都与C进行某种形式的互操作(因为C是大多数操作系统支持的共同标准)。虽然这不适用于客户端JavaScript(尽管一些原则仍与Native Client(NaCL)相关),但使用NodeJ,您可以使用node-gypcwrap调用C代码。一旦你进入C land,就可以使用Java Native Interface (JNI)调用Java(虽然可以通过让SWIG自动生成大部分样板来更容易地使用JNI从C调用Java代码为此而不是直接写入JNI规范。

  4. 与所有事情一样,各种方法都存在权衡:

    • 方法#1:
      • 优点:
        • 相对直截了当
        • 几乎适用于任何编程语言
        • 每个子系统与其他子系统完全隔离
        • 每个系统都可以用语言习惯的方式进行调试
      • 缺点:
        • 必须定义共享协议
          • 会导致冗余的重复代码
          • 协议必须保持同步
          • 更改必须向后兼容,否则会中断
          • 注意:protocol buffers可以为您提供帮助
        • 序列化/反序列化开销
        • channel可以增加其他开销(例如,如果通过Internet进行通信,而不是通过UNIX域套接字在同一台机器上进行通信)
        • 必须考虑通信机制的安全性
          • 子系统之间的数据加密
          • 端点的访问控制
    • 方法#2:
      • 优点:
        • 没有序列化/反序列化开销
        • 可以使用目标语言的惯用语来调试最终系统
      • 缺点:
        • 并非所有语言都可以从一个语言转移到另一个语言
        • 即使转录器支持这两种语言:
          • 通常只支持语言的一个子集
          • 可能需要修改/修改代码以允许其转换
          • 可能需要修复/修改“转发器”
          • 翻译中略有不同的语义可能导致细微的,令人惊讶的错误
        • 子系统之间没有隔离
    • 方法#3:
      • 优点:
        • 没有序列化/反序列化开销
        • 比方法#2更多的支持
        • 无需用任何一种语言重写原始代码
      • 缺点:
        • 必须成为SWIG等神秘工具的专家
        • 结果很难调试
          • NodeJS代码的stacktraces突然包含C,JVM,Java代码
          • 调试工具不容易跨越语言(例如,最终可能会通过JVM代码解释Java,而不是单步执行实际的Java代码)。
        • 对象的所有权,跨语言的垃圾收集可能导致令人惊讶/难以处理错误,如果所有权语义未正确编码
        • 语言之间不同的线程模型或语言之间的其他语义不匹配会导致整个系统错误/难以调试

    使用方法#1和方法#3的系统(以及使用方法#2的系统听证会),我强烈建议尽可能使用方法#1;只有当你发现序列化开销难以维持(并且你无法优化通信协议/机制来处理这个问题)时,我才会冒险进入其他领域。话虽如此,如果语言非常相似(如从TypeScript到JavaScript的转换),方法#2可以成功,如果使用这种机制的范围非常有限(例如只需暴露一个),方法#3就可以成功这种方式很小但经常被称为/性能敏感的功能。)

答案 1 :(得分:0)

我对Java知之甚少,但是您不能使用节点Java桥吗?

https://github.com/joeferner/node-java

我认为这是使用node-gyp的,因此很可能沿#3的方向工作

答案 2 :(得分:0)

如果您的方法是public static void main,则可以使用node-java-caller