从Node.js应用程序调用java程序

从Node.js应用程序调用java程序,java,node.js,express,Java,Node.js,Express,据我所知,在node.js应用程序中运行java文件有几种方法。一种方法是生成一个子进程:(java代码与依赖项打包在一个可执行的jar中) 另一种方法是使用java-npm模块(),它是JNI上的包装器(这将允许我创建对象,设置和获取属性,运行方法) 在生产环境中,当我希望我的node.js(Express)服务器调用java程序(它只是将一个图像保存到本地目录)时,请告诉我哪种方法更好(就最佳实践而言)。另外,还有一长串的参数,我需要将它们传递给main类,在命令行上这样做有点困难。我应该从

据我所知,在
node.js
应用程序中运行
java
文件有几种方法。一种方法是生成一个子进程:(java代码与依赖项打包在一个可执行的
jar
中)

另一种方法是使用
java-npm
模块(),它是
JNI
上的包装器(这将允许我创建
对象
,设置和获取
属性
,运行
方法

在生产环境中,当我希望我的
node.js
Express
)服务器调用
java
程序(它只是将一个图像保存到本地目录)时,请告诉我哪种方法更好(就最佳实践而言)。另外,还有一长串的
参数
,我需要将它们传递给
main
类,在命令行上这样做有点困难。我应该从输入文件读取
java
程序吗?

1)如果使用
exec
,您将运行整个程序,而如果使用JNI接口,您将能够直接与jar中的库和类交互,并执行诸如调用单个函数或创建类实例之类的操作。然而,如果您不需要类似的东西,我认为使用
exec
要简单得多,而且运行速度也会更快。听起来您只是想将Java应用程序作为一个独立进程运行,并记录应用程序是否成功完成或出现错误。我想说,使用
exec
可能更好。以这种方式执行子进程对于调试来说也要好得多,调试JNI错误有时会非常困难


2) 至于是否从文件中读取参数,是的,从某种文件中读取通常比直接传入参数更好。它不太容易出现人为错误(即每次键入参数),而且更易于配置。如果像QA工程师这样的人只需要编辑配置文件来交换选项,他们不需要了解整个代码库来测试它。就我个人而言,我编写的每个Java程序都使用配置文件。

您可以使用部署工具包并通过jnlp运行jar。
通过jnlp运行jar的优点是能够将参数从javascript传递到jar。通过这种方式,您可以动态定制java程序。

对于这种类型的问题您希望通过以下方式解决它:

  • 在我的语言/框架中,有没有一种体面的方式来运行带有参数的进程
  • 有没有一个像样的方法来处理程序输出
根据经验,处理进程中的参数的一种好方法是将它们作为(字符串)数组传递。这是有利的,因为您不必求助于不必要的字符串插值和操作。它也更具可读性,这在这个问题设置中是一个加号

处理输出的一种好方法是使用基于侦听器/事件的模型。这样,您就可以适当地响应事件,而不是为stderr和stdout设置if块。同样,这使事情可读,让您以更易于维护的方式处理输出

如果您再深入一点,您还必须解决一个问题,即如何将环境变量注入目标程序中。例如,您可能希望在将来使用调试器或更少内存运行java,因此您的解决方案也需要满足这一要求


这只是解决这类问题的一种方法。如果node是您的平台,那么看看哪些支持所有这些技术。

我们可以通过生成.jar文件来运行整个java项目,并使用shell中的命令运行它,然后运行该shell文件。为了从nodejs项目中运行java代码,我们知道该项目可以是java、js模块的混合体。 在节点中调用exec()函数,创建一个子进程来执行shell文件,该shell文件具有运行.sh文件的命令,并且还可以从use.eg中传递一些参数

let fileName = 'someFile.txt';
let userName = 'Charlie Angle'; 
exec(`sh run.sh --context_param
paramFilePath="./storage/${fileName}" --context_param userName="${userName}"`, (error, stdout, stderr) => {// Some code based on execution of above command})

您只需使用模块节点java调用者调用带有类路径和参数的java命令,它嵌入对spawn的调用,如果系统上没有java,它也会自动安装java


如果您的输入足够复杂,我建议您创建表示输入数据的POJO,并使用Jackson YAML factory将您的输入反序列化为JSON或YAML文件(YAML也将解析JSON)。然后使用Args4J并接受JSON作为文件选项,还有一个类似于-i的输入选项,它告诉您从stdin读取输入,以便JSON可以从另一个程序导入。这让他们有了一个模板,他们可以用这个模板进行简单的令牌替换,然后通过管道连接到您的程序。或者你也可以在node上做同样的事情。进一步考虑,通过stdout/stdin将数据发送到java程序似乎是最有意义的。创建一个临时文件然后从java程序加载是不必要的,它引入了一个IO瓶颈。我可以传递不是
字符串
s(比如
数组
)的参数吗?我刚刚尝试过。我传递了“['asd'、'qwe'、'zxc']`并将其作为逗号分隔的字符串“asd、qwe、zxc”接收,该字符串可以很容易地用逗号拆分并转换为ArrayEAH,但其中一些元素中也可以有逗号。
let fileName = 'someFile.txt';
let userName = 'Charlie Angle'; 
exec(`sh run.sh --context_param
paramFilePath="./storage/${fileName}" --context_param userName="${userName}"`, (error, stdout, stderr) => {// Some code based on execution of above command})