Java ProcessBuilder - 启动另一个进程/JVM - HowTo?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3263130/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 17:51:04  来源:igfitidea点击:

ProcessBuilder - Start another process / JVM - HowTo?

javatestingprocessjvmfork

提问by Stefan K.

I'm writing a network app, where each Client has a Singleton ClientManager. For testing, I would like to create several clients (each in their own VM / process) without starting the program by hand n-times.

我正在编写一个网络应用程序,其中每个客户端都有一个单例 ClientManager。为了测试,我想创建多个客户端(每个客户端都在自己的 VM/进程中),而无需手动启动程序 n 次。

The following two questions on stackoverflow already describe how-to do that:

stackoverflow 上的以下两个问题已经描述了如何做到这一点:

My Code is based on these, but it's not working:

我的代码基于这些,但它不起作用:

  • The main program doesn't continue after spawn is called.
  • The spawned code doesn't get executed.
  • 调用 spawn 后主程序不会继续。
  • 生成的代码不会被执行。

Here's the complete code using ProcessBuilder:

这是使用ProcessBuilder的完整代码:

public class NewVM {
  static class HelloWorld2 {
    public static void main(String[] args) {
      System.out.println("Hello World");
      System.err.println("Hello World 2");
    }
  }
  public static void main(String[] args) throws Exception {
    startSecondJVM(HelloWorld2.class, true);
    startSecondJVM(HelloWorld2.class, false);
    System.out.println("Main");
  }
  public static void startSecondJVM(Class<? extends Object> clazz, boolean redirectStream) throws Exception {
    System.out.println(clazz.getCanonicalName());
    String separator = System.getProperty("file.separator");
    String classpath = System.getProperty("java.class.path");
    String path = System.getProperty("java.home")
            + separator + "bin" + separator + "java";
    ProcessBuilder processBuilder = 
            new ProcessBuilder(path, "-cp", 
            classpath, 
            clazz.getCanonicalName());
    processBuilder.redirectErrorStream(redirectStream);
    Process process = processBuilder.start();
    process.waitFor();
    System.out.println("Fin");
  }
}

What am I doing wrong???

我究竟做错了什么???

Btw:

顺便提一句:

  • I'm using Eclipse.
  • The Singleton problem is a simplifiedexample. Please do notsuggest creating a factory.
  • 我正在使用 Eclipse。
  • 单例问题是一个简化的例子。请不要建议创建一个工厂。

Solution:HelloWorld2 mustn't be an inner class.

解决方案:HelloWorld2 不能是内部类。

采纳答案by emory

I suggest you make HelloWorld2 a top level class. It appears java expects a top level class.

我建议您将 HelloWorld2 设为顶级类。看来java需要一个顶级类。

This is the code I tried.

这是我试过的代码。

class Main
{
    static class Main2
    {
        public static void main ( String [ ] args )
        {
            System . out . println ( "YES!!!!!!!!!!!" ) ;
        }
    }

    public static void main ( String [ ] args )
    {
        System . out . println ( Main2 . class . getCanonicalName ( ) ) ;
        System . out . println ( Main2 . class . getName ( ) ) ;
    }
}

class Main3
{
    public static void main ( String [ ] args )
    {
        System . out . println ( "YES!!!!!!!!!!!" ) ;
    }
}
  1. getCanonicalNameand getNamereturn different names. Which one is right? They are both wrong.
  2. Main3 works.
  1. getCanonicalNamegetName返回不同的名称。哪一个是对的?他们都错了。
  2. Main3 作品。

回答by Carl Smotricz

I think I see a fix for part of the problem: process.waitFor()prevents control from returning to main() before the subprocess ends.

我想我看到了部分问题的修复:process.waitFor()防止在子进程结束之前控制返回到 main()。

To figure out why your spawned process isn't starting, I'd recommend printing out all the arguments to the ProcessBuilderconstructor and checking that a hand-called JVM called with those arguments succeeds. In particular, you need that class name to be the name of a class having a static void main(String[]).

要弄清楚为什么您的衍生进程没有启动,我建议将所有参数打印到ProcessBuilder构造函数并检查使用这些参数调用的手动调用的 JVM 是否成功。特别是,您需要该类名是具有static void main(String[]).