19

I want to be able to launch a Java server process from an existing java application and monitor the stdoutput and stderror and redirect that output to a file. Is the best approach to use 'Runtime.exec' and treat the app like any other OS process or is there something more suited for new JVMs.

This is on Java 1.5

2
  • If you do decide to use Runtime, read "When Runtime.exec Won't..." Commented Jan 26, 2009 at 17:37
  • Yes, having a means to tell the JVM to execute a new JVM that ran a given class main() method would be nice. I guess that would only be acceptable if the new JVM used the current class-loader, otherwise which class implementations were used would be too unpredictable. But that would be very hard, perhaps impossible, because of the need to prevent a process starting the JVM with a trojan class-loader. Commented Mar 21, 2013 at 18:40

2 Answers 2

18

Instead of Runtime, you should probably use ProcessBuilder, though I don't know if something else is even more appropriate in your case (running a Java process in particular).

Sign up to request clarification or add additional context in comments.

2 Comments

ProcessBuilder is exactly the tool for this purpose. You can easily hook the out/err of the process and even redirect the err to out so you don't have to monitor two streams (unless you want to). You will have to write the stream I/O code yourself ... see BufferedInputReader.
And what if this external process hangs, process.destroy will never be able to kill it, in linux you can send a SIGINT but then it will kill the whole program not just this process, launching something which is not tested, might be on the safe side to launch in altogether a new process unless there is a way to kill this particular process. or if there is then tell me, i laucnh e.g nslookup and then there is no way to kill it, (except the quit) so how can you really kill the process if it hangs??
12

I know I am late in this thread, but in case someone needs it, in my experience, it is easier to use ANT to launch a Java application. This has the benefit of being platform independent. Here is a sample class that does that:

package com.trilliantnetworks.scheduler.quartz.test;

import java.io.File;
import java.io.PrintStream;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DefaultLogger;
import org.apache.tools.ant.DemuxOutputStream;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Echo;
import org.apache.tools.ant.taskdefs.Java;
import org.apache.tools.ant.types.Path;

public class MyLaunchTest {

public static void main(String[] args) {

    Project project = new Project();
    project.setBaseDir(new File(System.getProperty("user.dir")));
    project.init();
    DefaultLogger logger = new DefaultLogger();
    project.addBuildListener(logger);
    logger.setOutputPrintStream(System.out);
    logger.setErrorPrintStream(System.err);
    logger.setMessageOutputLevel(Project.MSG_INFO);
    System.setOut(new PrintStream(new DemuxOutputStream(project, false)));
    System.setErr(new PrintStream(new DemuxOutputStream(project, true)));
    project.fireBuildStarted();

    System.out.println("running");
    Throwable caught = null;
    try {
        Echo echo = new Echo();
        echo.setTaskName("Echo");
        echo.setProject(project);
        echo.init();
        echo.setMessage("Launching Some Class");
        echo.execute();

        Java javaTask = new Java();
        javaTask.setTaskName("runjava");
        javaTask.setProject(project);
        javaTask.setFork(true);
        javaTask.setFailonerror(true);
        javaTask.setClassname(MyClassToLaunch.class.getName());
        Path path = new Path(project, new File(System.getProperty("user.dir") + "/classes").getAbsolutePath());
        javaTask.setClasspath(path);
        javaTask.init();
        int ret = javaTask.executeJava();
        System.out.println("java task return code: " + ret);

    } catch (BuildException e) {
        caught = e;
    }
    project.log("finished");
    project.fireBuildFinished(caught);
}
}

3 Comments

Hi, I've tried something similar to this but it always hang when it reach project.init(). It doesn't produce any error but just won't move from that line. Any comment on that?
Thanks for the idea with Ant to be platform-independent. Needed to run a executable-jar from within SoapUI which also has to run on a CI later.
you have to install apache ant and need to set "ANT_HOME" as a path variable. see mkyong.com/ant/how-to-install-apache-ant-on-windows

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.