为了账号安全,请及时绑定邮箱和手机立即绑定

从另一个 JVM 读取一个 JVM 的输入流

从另一个 JVM 读取一个 JVM 的输入流

泛舟湖上清波郎朗 2022-06-08 17:30:06
目标:使用 ProcessBuilder 从单独的 JVM(1) 初始化 JVM(2),从 JVM(2) 捕获结果输出并在 JVM(1) 的 JTextArea 中显示结果。情况:能够从 JVM(1) 内启动 JVM(2) 并将 JVM(2) 的结果输出捕获到 JVM(1) 内的 JTextArea。问题:在 JVM(1) 终止之前,JVM(2) 不会响应输入。启动 JVM(2) 的 VJM(1) 内的线程: Runnable runnable = () -> {      try {         JVMBooter.startSecondJVM();     } catch (Exception ex) {        Logger.getLogger(MyMenu.class.getName()).log(Level.SEVERE, null, ex);     } }; Thread t = new Thread(runnable); t.start();JVMBooter 源代码:import java.io.BufferedReader;import java.io.File;import java.io.InputStreamReader;public class JVMBooter {    public static void startSecondJVM() throws Exception {        ProcessBuilder pb = new ProcessBuilder("cmd", "/c", "startscript.bat");        File dir = new File("D:/Server");        pb.directory(dir);        Process p = pb.start();        BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));        String line = null;        ( (line = reader.readLine()) != null && ! line.trim().equals("--EOF--")) {            OutputFrame.textArea.append(line + "\n");        }    }}JVM(2) 在 startscript.bat 文件中启动:java -jar server.jar
查看完整描述

1 回答

?
神不在的星期二

TA贡献1963条经验 获得超6个赞

根据情况,可能需要读取错误流而不是输入流,例如,如果您的第二个 java 调用是-version或您调用的程序仅写入 stderr 而不是 stdout 获取错误流是正确的方法。


我写了这个 MCVE:


import java.io.*;


public class Starter {

    public static void main(String[] args) throws IOException {

        ProcessBuilder pb = new ProcessBuilder("./dosomething.sh");

        File dir = new File(new File(File.listRoots()[0], "tmp"), "2jvm");

        pb.directory(dir);

        Process p = pb.start();


        BufferedReader read = new BufferedReader(new InputStreamReader(p.getErrorStream()));

        String line;

        while ( (line = read.readLine() ) != null) {

            System.out.println("line: " + line);

        }

    }

}

在“dosomething.sh”中:


echo before

java -version

echo after

当我使用时,p.getInputStream我会得到“之前”和“之后”。当我使用时,p.getErrorStream我会得到 Java 版本信息。这对你来说也可能是真的。我建议您echo在批处理文件中添加行以查看它们是否被打印出来。


我还写了一个简单的 hello world,当我从中调用它时,dosomething.sh它会按预期打印到输入流中。写入标准错误是一个奇怪的怪癖。-version


为了完整起见,这里是我使用的 Hello World(它等待模拟长时间运行的服务器进程):


public class Caller {

  public static void main(String[] args) {

    synchronized(Caller.class) {

      for(int ii = 0; ii < 10; ii++) {

        try {

          Caller.class.wait(1000);

        } catch (Exception ex) {

          ex.printStackTrace();

        }

        System.out.println("Hello world! " + ii);

      }

    }

  }

}


查看完整回答
反对 回复 2022-06-08
  • 1 回答
  • 0 关注
  • 103 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信