是否可以以平台无关的方式使用Java应用程序的名称(而不是其位置)在单独的进程中加载Java应用程序?
我知道你可以通过…执行程序
Process process = Runtime.getRuntime().exec( COMMAND );
…这种方法的主要问题是,此类调用是特定于平台的。
理想情况下,我会将方法包装成像…这样简单的东西。
EXECUTE.application( CLASS_TO_BE_EXECUTED );
…并以形式传入应用程序类的完全限定名称CLASS_TO_BE_EXECUTED。
CLASS_TO_BE_EXECUTED
两个提示:
System.getProperty("java.home") + "/bin/java" 为你提供了Java可执行文件的路径。
System.getProperty("java.home") + "/bin/java"
((URLClassLoader) Thread.currentThread().getContextClassLoader()).getURL()帮助你重构当前应用程序的类路径。
((URLClassLoader) Thread.currentThread().getContextClassLoader()).getURL()
然后你EXECUTE.application就是(伪代码):
EXECUTE.application
Process.exec(javaExecutable, "-classpath", urls.join(":"), CLASS_TO_BE_EXECUTED)
这是已提供的其他一些答案的综合。Java系统属性提供了足够的信息,以我认为是平台独立的方式提供了java命令的路径和类路径。
public final class JavaProcess { private JavaProcess() {} public static int exec(Class klass, List<String> args) throws IOException, InterruptedException { String javaHome = System.getProperty("java.home"); String javaBin = javaHome + File.separator + "bin" + File.separator + "java"; String classpath = System.getProperty("java.class.path"); String className = klass.getName(); List<String> command = new LinkedList<String>(); command.add(javaBin); command.add("-cp"); command.add(classpath); command.add(className); if (args != null) { command.addAll(args); } ProcessBuilder builder = new ProcessBuilder(command); Process process = builder.inheritIO().start(); process.waitFor(); return process.exitValue(); } }
你将像这样运行此方法:
int status = JavaProcess.exec(MyClass.class, args);
我认为传入实际的类而不是名称的String表示形式是有意义的,因为无论如何该类都必须位于类路径中。