Execute a Java program from our Java program

后端 未结 14 1793
名媛妹妹
名媛妹妹 2020-12-01 17:24

I used

Runtime.getRuntime().exec(\"_____\")

but it throws a IOException as below:

java.io.IOException: Create         


        
相关标签:
14条回答
  • 2020-12-01 17:29

    How about just calling the main from your java program?

    Test.main(null);

    This worked fine for me

    0 讨论(0)
  • 2020-12-01 17:30

    Put ant lib in you classpath ( project lib ) and run this code :

    import org.apache.tools.ant.taskdefs.Execute;
    
    Execute exe = new Execute();
    exe.setCommandline(new String[]{"java", "-version"});
    exe.execute();
    
    0 讨论(0)
  • 2020-12-01 17:38

    You're trying to execute "C:/". You'll want to execute something like:

    "javaw.exe d:\\somejavaprogram\\program.jar"

    Notice the path separators.

    I'm assuming this is for an ad-hoc project, rather than something large. However, for best practice running external programs from code:

    • Don't hardcode the executable location, unless you're certain it will never change
    • Look up directories like %windir% using System.getenv
    • Don't assume programs like javaw.exe are in the search path: check them first, or allow the user to specify a location
    • Make sure you're taking spaces into account: "cmd /c start " + myProg will not work if myProg is "my program.jar".
    0 讨论(0)
  • 2020-12-01 17:38

    You can either launch another JVM (as described in detail in other answers). But that is not a solution i would prefer.

    Reasons are:

    • calling a native program from java is "dirty" (and sometimes crashes your own VM)
    • you need to know the path to the external JVM (modern JVMs don't set JAVA_HOME anymore)
    • you have no control on the other program

    Main reason to do it anyway is, that the other application has no control over your part of the program either. And more importantly there's no trouble with unresponsive system threads like the AWT-Thread if the other application doesn't know its threading 101.

    But! You can achieve more control and similar behaviour by using an elementary plugin technique. I.e. just call "a known interface method" the other application has to implement. (in this case the "main" method).

    Only it's not quite as easy as it sounds to pull this off.

    • you have to dynamically include required jars at runtime (or include them in the classpath for your application)
    • you have to put the plugin in a sandbox that prevents compromising critical classes to the other application

    And this calls for a customized classloader. But be warned - there are some well hidden pitfalls in implementing that. On the other hand it's a great exercise.

    So, take your pick: either quick and dirty or hard but rewarding.

    0 讨论(0)
  • 2020-12-01 17:38

    I had to do this recently.
    Here is how I did it, picking up only the relevant parts:

    private static final String[] straJavaArgs =
    {
       "?i/j2re/bin/java",
       "-ms64m",
       "-mx64m",
       "-Djava.ext.dirs=?i/lib;?i/jar/lib;?i/jar"
    };
    
    // ...
    
      // AppDesc appToRun;
      List<String> params = new ArrayList<String>();
      // Java exe and parameters
      params.addAll(ExpandStrings(straJavaArgs));
      // Common VM arguments
      params.addAll(Arrays.asList(AppDesc.GetCommonVMArgs()));
      // Specific VM arguments
      params.addAll(ExpandStrings(appToRun.GetVMArgs()));
      // The program to run
      params.add(appToRun.GetClass());
      // Its arguments
      params.addAll(ExpandStrings(appToRun.GetProgramArgs()));
      // The common arguments
      params.addAll(ExpandStrings(AppDesc.GetCommonProgramArgs()));
    
      ProcessBuilder processBuilder = new ProcessBuilder(params);
      process = processBuilder.start();
      return CaptureProcessOutput(); // Uses a StreamGobbler class
    
    protected ArrayList<String> ExpandStrings(String[] stra)
    {
      ArrayList<String> alResult = new ArrayList<String>();
      for (int i = 0; i < stra.length; i++)
      {
         // Super flexible, eh? Ad hoc for the current task, at least...
         alResult.add(stra[i]
               .replaceAll("\\?i", strInstallDir)
               .replaceAll("\\?c", strConfigDir)
         );
      }
      return alResult;
    }
    
    public enum AppDesc
    {
    // Enumerate the applications to run, with their parameters
    }
    

    Incomplete, if you need more details, just ask.

    0 讨论(0)
  • 2020-12-01 17:38

    I can't remember the exact code that I used to get this to work, but you have to pass "java.exe" (or the equivalent) as the executable, and then the class or jar to run as the parameter, with the correct working directory. So it's not as simple as just calling one method.

    0 讨论(0)
提交回复
热议问题