【问题标题】:Calling a java method in Node js [duplicate]在Node js中调用java方法[重复]
【发布时间】:2016-12-26 18:17:21
【问题描述】:

我正在尝试从节点 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 函数。

【问题讨论】:

  • 你不能像那样只调用其他语言的函数。您需要通过 Socket 或其他方式向您的 Java 程序发送消息/信号,然后在您的 Java 程序中解析该消息。
  • Java 和 Javascript 是两种完全不同的语言......你不妨尝试运行 C++ 或 Ruby,这不是 Node 理解的机会。
  • @BrandonIbbotson 虽然这可能是最好的方法,但也可以直接通过中间 C 接口和 JNI 调用来实现。
  • @MichaelAaronSafyan 我不知道这是可能的,听起来很有趣。
  • 你不能从Node.js调用Java函数但是你可以从命令行stackoverflow.com/questions/12892195/…调用jar或者可以使用github.com/joeferner/node-java

标签: javascript java node.js


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    我对java知之甚少,但你不能使用node-java桥吗?

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

    我认为这是使用 node-gyp,所以很可能会按照 #3 的方式工作

    【讨论】:

      【解决方案3】:

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

      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 领域,你可以使用 Java Native Interface (JNI) 调用 Java (尽管通过让 SWIG 为你自动生成大部分样板,使用 JNI 从 C 调用你的 Java 代码可能更容易实现,而不是直接写入 JNI 规范)。

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

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

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

      【讨论】:

        猜你喜欢
        • 2013-07-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-07
        相关资源
        最近更新 更多