简体   繁体   中英

How to Run a jar from another jar and show the console output from the first runnable during the execution

I'm running a jar file from another jar like here somebody answers but waiting for the process.

Process proc = Runtime.getRuntime().exec("java -jar A.jar" + stringParams);

try {
    proc.waitFor();
} catch (InterruptedException e) {
    e.printStackTrace();
}

InputStream in = proc.getInputStream();
InputStream err = proc.getErrorStream();

My problem comes when i have no feedback on the status of the program that is called, but i don't want my program continues beyond those lines. I would need the standard and error outputs but the results are shown when the execution is over. Is there any way of executing and getting those streams while the jar is still running?

Buffered/unbuffered

It seems like an issue with buffered output .

Executed process (in this case java -jar <path> ) buffers output and writes it only when it's done (in big chunks, we don't like that!)

So one way to go is execute process through unbuffering (very hacky tools):

  • unbuffered <command>
  • stdbuf -i0 -o0 -e0 <command>
  • use terminal emulation

Hacking

stdbuf is part of GNU tools.

https://www.gnu.org/software/coreutils/manual/html_node/stdbuf-invocation.html

unbuffered is part of expect package.

https://wiki.tcl.tk/3548

The key thing is making the program thinking that it's in interactive mode (like you are launching it from console).

The first two options are very hacky and do not work in all cases (idk if java command works with them?)

Emulation

The third option is most promising. We launch a program (terminal emulator) that emulates interactive terminal making program think it's working in real active session!

Pty4j

You might use pty4j too:

From there: https://github.com/traff/pty4j



    // The command to run in a PTY...
    String[] cmd = { "java", "-jar", "path_to_jar" };
    // The initial environment to pass to the PTY child process...
    String[] env = { "TERM=xterm" };

    PtyProcess pty = PtyProcess.exec(cmd, env);

    OutputStream os = pty.getOutputStream();
    InputStream is = pty.getInputStream();

    // ... work with the streams ...

    // wait until the PTY child process terminates...
    int result = pty.waitFor();

    // free up resources.
    pty.close();

Zt-exec

Maybe it's worth trying zt-exec ?

I have no idea how it executes commands.

But it may be it (I didn't test that).

Using https://github.com/zeroturnaround/zt-exec

new ProcessExecutor().command("java", "-jar path_to_jar")
        .redirectOutput(new LogOutputStream() {
            @Override
            protected void processLine(String line) {
                ...
            }
        })
        .execute();

That should work, but I didn't test that. In general, there are no ways to nicely resolve your problem.

Depending on what platforms you want to target consider using unbuffered , stdbuff or the (slowest) terminal emulation...

Please let me know if that helps and good luck! :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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