简体   繁体   English

是否可以使用Process Builder在Java中的进程之间共享变量

[英]Is it possible to share variable between processes in Java with Process Builder

Original message 原始信息

I'm currently working on several executable Jars being called by another Java process (or "Launcher) called by a scheduler. 我目前正在研究由调度程序调用的另一个Java进程(或“ Launcher”)调用的几个可执行Jar。

To do this, we use ProcessBuilder . 为此,我们使用ProcessBuilder However, we need to be able to share variable between the parent process and the child process (The executable JAR). 但是,我们需要能够在父进程和子进程(可执行JAR)之间共享变量。

I know it's possible to pass variable to the child process with the environment() method. 我知道可以使用environment()方法将变量传递给子进程。

What we need is to be able to share informations from the child process to the parent process (the process results, mostly files). 我们需要的是能够从子流程到父流程(流程结果,主要是文件)共享信息。 Is it possible? 可能吗? If it is, how so? 如果是,怎么办?

Update The two java processes are on the same computer and so share the same disk space. 更新两个Java进程位于同一台计算机上,因此共享相同的磁盘空间。 The Launcher process is called by a scheduler and this process cannot be changed. 调度程序将调用Launcher进程,并且无法更改此进程。

I know that using a file is probably the best solution but I was wondering if there was no other solution. 我知道使用文件可能是最好的解决方案,但是我想知道是否没有其他解决方案。

Thanks in advance for your help. 在此先感谢您的帮助。

A process is a sort of black box with which you can dialogue only via standard streams (input, output, error) or retrieving exit code of the process. 流程是一种黑匣子,您只能通过标准流(输入,输出,错误)或获取流程的退出代码进行对话。 All other systems needs an external way to communicate. 所有其他系统都需要外部通信方式。

So you can: 所以你可以:

  • Use the method exitValue() of the Process as a form of communication between child and parent. 使用Process的方法exitValue()作为子代与父代之间的一种通信形式。

  • Intercept the output of the child process using the getInputStream() method. 使用getInputStream()方法拦截子进程的输出。

  • Share data with external resources (files, databases or opening communication sockets for example). 与外部资源(例如文件,数据库或打开通讯套接字)共享数据。

You need bidirectional communication between processes . 您需要流程之间的双向通信 You can choose from three alternatives: 您可以从以下三种选择中进行选择:

  1. Asynchronous low level: Use a pre-stablished disk file for each communication: One file to write data from each child process to the parent process, and another to write data from the parent process to the child process (if needed). 异步低级:每次通信使用预先设置的磁盘文件:一个文件将数据从每个子进程写入父进程,另一个文件将数据从父进程写入子进程(如果需要)。

  2. Synchronous generic server/client level: On every process that must receive data (either the parent process or either each child process), open a ServerSocket and accept requests according to your own protocol (typically this must be done on a secondary thread). 同步通用服务器/客户端级别:在必须接收数据的每个进程(父进程或每个子进程)上,打开ServerSocket并根据您自己的协议接受请求(通常必须在辅助线程上完成)。

  3. Synchronous specific Java RMI level: This is the most advanced, flexible and usable alternative you can get: Design and implement an RMI interface and deploy it as a server on each process that must receive data, and also deploy it as client on each process that must send data. 特定于同步的Java RMI级别:这是您可以获得的最先进,灵活和可用的替代方案:设计和实现RMI接口,并将其作为服务器在必须接收数据的每个进程中进行部署,并作为客户端在每个需要接收数据的进程中进行部署必须发送数据。

What you need to do is not to execute your process directly, but rather create a (batch) script which executes the command and after this it writes the value of the variable to a file. 您需要执行的操作不是直接执行流程,而是创建一个(批处理)脚本来执行命令,然后将变量的值写入文件。 Then make the ProcessBuilder execute the (batch) script. 然后使ProcessBuilder执行(批处理)脚本。 Then, before calling another process, read the file, and pass the variable value to the ProcessBuilder using the environment() method you mention. 然后,在调用另一个进程之前,请阅读文件,然后使用您提到的environment()方法将变量值传递给ProcessBuilder。

So the (batch) script looks as follows: 因此,(批处理)脚本如下所示:

<your command>
echo $variable > file.txt

And then you execute shell with the script filename as an argument: 然后以脚本文件名作为参数执行shell:

bash batchscript.sh

In windows, it works the same, except you want to execute 在Windows中,它的工作原理相同,只是要执行

cmd /c batchscript.cmd

There was a product called Terracotta that allowed to share object across multiple JVM instances. 有一种名为Terracotta的产品,允许在多个JVM实例之间共享对象。 The onwer company still have open source versions of their products but I don't know them anymore. 上级公司仍具有其产品的开源版本 ,但我不再了解它们。

If you want to use RMI as suggested by Little Santi you may use Spring-remoting to make it easier. 如果要按照Little Santi的建议使用RMI,则可以使用Spring-remoting使其更容易。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM