从Java应用程序中使用Runtime.exec启动JVM进程?
从上述内容中可以看出,这个问题的出现原因是在使用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进程时可能出现的问题。
问题出现的原因是使用Runtime.exec()方法来启动JVM进程可能不是最合适的方法,建议使用ProcessBuilder类来代替。使用ProcessBuilder可以轻松地连接进程的输出和错误,并且还可以将错误重定向到输出,这样就不需要监视两个流了。需要自己编写流的输入/输出代码,可以参考BufferedInputReader类的使用。
如果外部进程hangs(挂起),使用process.destroy()方法将无法终止它。在Linux中,可以发送SIGINT信号来终止进程,但这样会终止整个程序,而不仅仅是该进程。为了安全起见,启动一个未经测试的进程最好是在一个全新的进程中启动,除非有一种方法可以终止特定的进程。如果存在这样的方法,请告诉我,例如我启动了nslookup,然后没有办法终止它,除非使用quit命令。那么如果进程挂起了,如何真正终止它呢?