如何在Java中的新进程中启动“main”?

问题很简单。 如何在另一个java进程中启动main方法? 现在我这样做:

startOptions = new String[] {"java", "-jar", "serverstart.jar"}; new ProcessBuilder(startOptions).start(); 

但他们要求我不要使用外部.jar文件。 serverstart.jar显然有一个main方法,但是可以在不调用.jar文件的情况下在另一个进程中调用该main方法吗?

我在考虑这样的事情:

 new ProcessBuilder(ServerStart.main(startOptions)).start(); 

但我不知道是否存在类似的东西。

亲切的问候,

假设一个带有新类加载器的新线程是不够的(我会投票支持这个解决方案),我知道你需要创建一个独特的进程来调用类中的main方法,而不必在其中声明为“jar main方法”。清单文件 – 因为您不再具有不同的serverstart.jar。

在这种情况下,您可以简单地调用java -cp $yourClassPath your.package.ServerStart ,就像在没有(或不想使用)清单Main-Class时运行任何Java应用程序一样。

从java创建新的“java”进程是不可能的,因为两个进程不能共享一个JVM 。 (见这个问题和接受的答案 )。


如果您可以使用自定义ClassLoader来创建新的Thread而不是Process 。 它就近了,你可以进入一个新的过程 。 所有静态和最终字段都将重新初始化!

另请注意, "ServerStart类(以下示例)必须位于当前正在执行的JVM的类路径中”:

 public static void main(String args[]) throws Exception { // start the server start("ServerStart", "arg1", "arg2"); } private static void start(final String classToStart, final String... args) { // start a new thread new Thread(new Runnable() { public void run() { try { // create the custom class loader ClassLoader cl = new CustomClassLoader(); // load the class Class clazz = cl.loadClass(classToStart); // get the main method Method main = clazz.getMethod("main", args.getClass()); // and invoke it main.invoke(null, (Object) args); } catch (Exception e) { e.printStackTrace(); } } }).start(); } 

这是自定义类加载器:

 private static class CustomClassLoader extends URLClassLoader { public CustomClassLoader() { super(new URL[0]); } protected java.lang.Class findClass(String name) throws ClassNotFoundException { try{ String c = name.replace('.', File.separatorChar) +".class"; URL u = ClassLoader.getSystemResource(c); String classPath = ((String) u.getFile()).substring(1); File f = new File(classPath); FileInputStream fis = new FileInputStream(f); DataInputStream dis = new DataInputStream(fis); byte buff[] = new byte[(int) f.length()]; dis.readFully(buff); dis.close(); return defineClass(name, buff, 0, buff.length, (CodeSource) null); } catch(Exception e){ throw new ClassNotFoundException(e.getMessage(), e); } } } 

我建议从java调用一个shellcript并使用它来启动新进程(如果你不能只使用另一个线程)。

您可以使用Reflection(java.lang.reflect包)执行此操作。

 public static void main(String[] args) throws Exception { Class c = Class.forName("ServerStart"); Class[] argTypes = { args.getClass() }; Method m = c.getMethod("main", argTypes); Object passedArgv[] = { args }; m.invoke(null, passedArgv); }