10

I used

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

but it throws a IOException as below:

java.io.IOException: CreateProcess: c:/ error=5
  at java.lang.Win32Process.create(Native Method)
  at java.lang.Win32Process.<init>(Win32Process.java:63)
  at java.lang.Runtime.execInternal(Native Method

I don't know whether I have the problem with specifying the path or something else. Can anyone please help me with the code.

vidstige
  • 12,492
  • 9
  • 66
  • 110
Arun
  • 580
  • 6
  • 11
  • 17

14 Answers14

10

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".
Mark
  • 6,269
  • 2
  • 35
  • 34
  • Yes, it works fine for simple files, but it's a bad habit to get into. What happens when you try to run a command line, like "cmd /c cd ../myfolder&make" or try to read something beginning "\\?\"?. Not to mention the confusion when the user sees "c:/users\myname/desktop\". – Mark Feb 02 '09 at 16:01
  • Things get messy if you're trying to run `cmd.exe` from inside another program. They get even worse if you want to use `start` as that has some really *strange* options... – Donal Fellows Apr 07 '10 at 13:46
8

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.

Stroboskop
  • 4,327
  • 5
  • 35
  • 52
7
java.io.IOException: CreateProcess: c:/ error=5
        at java.lang.Win32Process.create(Native Method)
        at java.lang.Win32Process.&lt;init&gt;(Win32Process.java:63)
        at java.lang.Runtime.execInternal(Native Method)

If I recall correctly, error code 5 means access denied. This could be because your path is incorrect (trying to execute "c:/") or you are bumping against your OS security (in which case, look at the permissions).

If you are having trouble locating the Java executable, you can usually find it using system properties:

public class LaunchJre {

    private static boolean isWindows() {
        String os = System.getProperty("os.name");
        if (os == null) {
            throw new IllegalStateException("os.name");
        }
        os = os.toLowerCase();
        return os.startsWith("windows");
    }

    public static File getJreExecutable() throws FileNotFoundException {
        String jreDirectory = System.getProperty("java.home");
        if (jreDirectory == null) {
            throw new IllegalStateException("java.home");
        }
        File exe;
        if (isWindows()) {
            exe = new File(jreDirectory, "bin/java.exe");
        } else {
            exe = new File(jreDirectory, "bin/java");
        }
        if (!exe.isFile()) {
            throw new FileNotFoundException(exe.toString());
        }
        return exe;
    }

    public static int launch(List<String> cmdarray) throws IOException,
            InterruptedException {
        byte[] buffer = new byte[1024];

        ProcessBuilder processBuilder = new ProcessBuilder(cmdarray);
        processBuilder.redirectErrorStream(true);
        Process process = processBuilder.start();
        InputStream in = process.getInputStream();
        while (true) {
            int r = in.read(buffer);
            if (r <= 0) {
                break;
            }
            System.out.write(buffer, 0, r);
        }
        return process.waitFor();
    }

    public static void main(String[] args) {
        try {
            Runtime.getRuntime().exec("c:/");

            List<String> cmdarray = new ArrayList<String>();
            cmdarray.add(getJreExecutable().toString());
            cmdarray.add("-version");
            int retValue = launch(cmdarray);
            if (retValue != 0) {
                System.err.println("Error code " + retValue);
            }
            System.out.println("OK");
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

(Tested Windows XP, Sun JRE 1.6; Ubuntu 8.04, OpenJDK JRE 1.6)

This is the equivalent of running:

java -version

You may also want to look at the "java.library.path" system property (and "path.separator") when trying to locate the executable.

McDowell
  • 107,573
  • 31
  • 204
  • 267
2

How about just calling the main from your java program?

Test.main(null);

This worked fine for me

Dean
  • 171
  • 7
  • Hey buddy it's working 4 me too, but I need to use Runtime class. That's the big issue.. – Arun Feb 02 '09 at 09:01
  • 5
    Calling "main" is not without side-effects. Even if you ensure classes get unloaded when you're done with them by using your own class loaders, invoked applications may alter the global state of the JVM in ways that conflict with your application. – McDowell Feb 02 '09 at 11:49
2

Is there any reason you can't just call it directly in your Java code?

If there is a reason I've not tried it for executing a Java Program but you could try Jakarta Commons Exec works well for executing most programs.

Mark Davidson
  • 5,503
  • 5
  • 35
  • 54
2

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.

PhiLho
  • 40,535
  • 6
  • 96
  • 134
2
public class Test {    
  public static void main(String[] args) throws Exception {    
    Process p = Runtime.getRuntime().exec("\"c:/program files/windows/notepad.exe\"");
    p.waitFor();
  }

}

The above works quite well, instead of passing \"c:/program files/windows/notepad.exe\" as the arguments for the executable, use the path to your program, I'm not sure if this solution is JVM version dependent, or if it can use relative paths.

guerda
  • 23,388
  • 27
  • 97
  • 146
  • The code provided by jex above is dangerous. Read the following article that explains it in greater details: http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html It also explains how to call external native program from your Java code properly. – egorpe Feb 03 '09 at 00:18
1

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();
Edgard Leal
  • 2,592
  • 26
  • 30
1

You must pass the path of your executable at the exec method. Are you really trying to execute the "-" process?

Also, have a look at this for some useful tips.

kgiannakakis
  • 103,016
  • 27
  • 158
  • 194
0

First you compile the prog-A code and convert to jar file(ie:In NetBeans Shift-F11)and the path is of netbeans(NetBeansProjects/prog-A/dist/prog-A.jar)

 public class ProgA {

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    System.out.println("Helllo print thr ProgA");

}
}
}

Second open the new project in prog-B and add the libraries, and select the jar and give to the prog-A.jar file and write the two line in your program

public class ProgB {


public static void main(String[] args) {
    ProgA progA = new  ProgA();
    String arg[] = null;
    progA.main(arg);
}
}
Reegan Miranda
  • 2,879
  • 6
  • 43
  • 55
0

I agree with Ushsa Varghese, if you just want to run your jar file instead of compiling the .java file that is in the same directory you are executing your application from try the code below. This is the same as executing your java application from the command line so you have to invoke the jvm in order to run your application. Also make sure you have the complete path to your jar file the example below assumes that the jar file is in the same directory as the application that is executing the code below. keep in mind this is system dependent code.

try {
  Runtime runTime = Runtime.getRuntime();
  Process process = runTime.exec("java -jar deleteDriveC.jar");
} catch (IOException ex) {
  //jar file doesnt exist
  //Logger.getLogger(this.class.getName()).log(Level.SEVERE, null, ex);
}
jay
  • 1
0

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.

Ray Hidayat
  • 16,055
  • 4
  • 37
  • 43
0

I had a similiar problem. I needed to run a section of Java code in a seperate VM as it invoked native code via JNI that occasionally blew up taking out the entire VM.

I cheated a little though. I initially used Runtime to invoke a simple batch command file and put the work-in-progress java command in there. This enabled me to tweak it as needed and to run the command in a DOS prompt for easy testing. Once it was finished I simply copied the result into the Runtime invocation.

Michael Rutherfurd
  • 13,815
  • 5
  • 29
  • 40
-1

The answer is simple all you have to do is put the code -

$ process p = Runtime.getRuntime().exec("javac factorial.java"); in the try catch block

The code would look like this -

try
{
process p = Runtime.getRuntime().exec("javac factorial.java");
}
catch(IOException e)
{
e.printStackTrace();
}

Hey I think this should work. Atleast for me it did work

  • hmm ... can't really believe that you can execute a java _source_ file. All that might happen - depending on your local setup - is that an editor/IDE associated with the file extension is fired up :-) – kleopatra Feb 28 '12 at 11:02
  • nopes. you have to believe. you can execute a java source file. That is you can get a class file. But the $java factorial command will not work. Well i have not found out. There may be ways that could be done. – Ushsa Varghese Feb 29 '12 at 05:14