从Java应用程序中使用Runtime.exec启动JVM进程?

12 浏览
0 Comments

从Java应用程序中使用Runtime.exec启动JVM进程?

我想要能够从现有的Java应用程序中启动一个Java服务器进程,并监控stdoutput和stderror,并将输出重定向到一个文件。最好的方法是使用“Runtime.exec”并将该应用程序视为其他任何操作系统进程,还是有更适合新的JVM的方法?

这是在Java 1.5上。

0
0 Comments

从上述内容中可以看出,这个问题的出现原因是在使用Java应用程序中通过Runtime.exec()启动JVM进程时出现了问题。对于这个问题,可以使用ANT来启动Java应用程序,这样做具有跨平台的优势。

解决方法是使用ANT的Java任务来启动Java应用程序。下面是一个示例类的代码,其中使用了ANT来启动Java应用程序:

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);
    }
}

其中,使用ANT的Java任务来设置项目和启动Java应用程序。在示例中,使用了Echo任务来输出一条消息,然后使用Java任务来启动一个名为MyClassToLaunch的类。还使用了路径来设置类路径,并使用executeJava()方法来执行Java任务。

对于问题中提到的hang的情况,可能是由于项目初始化过程中遇到了某些问题导致的。具体原因需要进一步分析和调试。

总之,通过使用ANT来启动Java应用程序,可以实现平台无关性,并且能够解决使用Runtime.exec()启动JVM进程时可能出现的问题。

0
0 Comments

问题出现的原因是使用Runtime.exec()方法来启动JVM进程可能不是最合适的方法,建议使用ProcessBuilder类来代替。使用ProcessBuilder可以轻松地连接进程的输出和错误,并且还可以将错误重定向到输出,这样就不需要监视两个流了。需要自己编写流的输入/输出代码,可以参考BufferedInputReader类的使用。

如果外部进程hangs(挂起),使用process.destroy()方法将无法终止它。在Linux中,可以发送SIGINT信号来终止进程,但这样会终止整个程序,而不仅仅是该进程。为了安全起见,启动一个未经测试的进程最好是在一个全新的进程中启动,除非有一种方法可以终止特定的进程。如果存在这样的方法,请告诉我,例如我启动了nslookup,然后没有办法终止它,除非使用quit命令。那么如果进程挂起了,如何真正终止它呢?

0