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

目标:使用 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


泛舟湖上清波郎朗
浏览 104回答 1
1回答

神不在的星期二

根据情况,可能需要读取错误流而不是输入流,例如,如果您的第二个 java 调用是-version或您调用的程序仅写入 stderr 而不是 stdout 获取错误流是正确的方法。我写了这个 MCVE:import java.io.*;public class Starter {&nbsp; &nbsp; public static void main(String[] args) throws IOException {&nbsp; &nbsp; &nbsp; &nbsp; ProcessBuilder pb = new ProcessBuilder("./dosomething.sh");&nbsp; &nbsp; &nbsp; &nbsp; File dir = new File(new File(File.listRoots()[0], "tmp"), "2jvm");&nbsp; &nbsp; &nbsp; &nbsp; pb.directory(dir);&nbsp; &nbsp; &nbsp; &nbsp; Process p = pb.start();&nbsp; &nbsp; &nbsp; &nbsp; BufferedReader read = new BufferedReader(new InputStreamReader(p.getErrorStream()));&nbsp; &nbsp; &nbsp; &nbsp; String line;&nbsp; &nbsp; &nbsp; &nbsp; while ( (line = read.readLine() ) != null) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println("line: " + line);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}在“dosomething.sh”中:echo beforejava -versionecho after当我使用时,p.getInputStream我会得到“之前”和“之后”。当我使用时,p.getErrorStream我会得到 Java 版本信息。这对你来说也可能是真的。我建议您echo在批处理文件中添加行以查看它们是否被打印出来。我还写了一个简单的 hello world,当我从中调用它时,dosomething.sh它会按预期打印到输入流中。写入标准错误是一个奇怪的怪癖。-version为了完整起见,这里是我使用的 Hello World(它等待模拟长时间运行的服务器进程):public class Caller {&nbsp; public static void main(String[] args) {&nbsp; &nbsp; synchronized(Caller.class) {&nbsp; &nbsp; &nbsp; for(int ii = 0; ii < 10; ii++) {&nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Caller.class.wait(1000);&nbsp; &nbsp; &nbsp; &nbsp; } catch (Exception ex) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ex.printStackTrace();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; System.out.println("Hello world! " + ii);&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java