26

I have a Main.java and Test.java classes that I want to compile and run Main.java in Test.java code. Here is my code

    Process pro1 = Runtime.getRuntime().exec("javac Main.java");
    pro1.waitFor();
    Process pro2 = Runtime.getRuntime().exec("java Main");

    BufferedReader in = new BufferedReader(new InputStreamReader(pro2.getInputStream()));
    String line = null;

    while ((line = in.readLine()) != null) {
        System.out.println(line);
    }

I just print "ok" in Main.java but this code doesn't print anything. What is the problem ?

  • Looks like you're looking for http://docs.codehaus.org/display/JANINO/Home ;) . – phihag Jan 30 '11 at 11:44
  • @phihag it is just java code example. I will generalize it with c/c++ code and ohters –  Jan 30 '11 at 11:45
  • 1
    Aren't you supposed to use `Process.getOutputStream`? – Sasha Goldshtein Jan 30 '11 at 11:47
  • What are the `exitValue()` 's of the processes? What do they output in ErrorStreams? – adamax Jan 30 '11 at 11:48
  • 3
    Works fine for me. Are you sure that java and javac are in the PATH? Does it work if you run those commands from the command line? You may also wish to use the javax.tools package for compiling if you want more control over the compiling process. – Sergei Tachenov Jan 30 '11 at 11:52
  • @Sasha, no, stdout of the process goes into getInputStream(). It is confusing no matter how you name the methods, as the output from one side is the input at another side. – Sergei Tachenov Jan 30 '11 at 11:54
  • @Sergey I just run this code in my netbeans project –  Jan 30 '11 at 11:55
  • @hilal, disregard my previous comment. I missed that you call exitValue(). You can't do this before the process is finished. Confusion is right. – Sergei Tachenov Jan 30 '11 at 12:07
  • @hilal, oh, sorry again. I also missed that you actually edited your code. The first version was correct and it was working properly for me. You still need to check if the processes are started correctly (after you try to start them), then read processes' error streams (while they are running) and check their exitValue()s (after they have finished). – Sergei Tachenov Jan 30 '11 at 12:11
  • @Segey thanks for your comment. I think it is related to my classpath but I can't solve this problem –  Jan 30 '11 at 12:24
  • Try this: `Runtime.getRuntime().exec("javac Main.java", null, new File("/path"));` where "/path" is the absolute path to the directory where your Main.java is located. And the same with `java Main` – adamax Jan 30 '11 at 12:36
  • @hilal, I don't think classpath has anything to do with it. I'd suspect PATH instead. – Sergei Tachenov Jan 30 '11 at 12:50
  • @hilal, sorry, PATH has nothing to do with it. If one of the commands was unavailable, it would break with an IOException. – Sergei Tachenov Jan 30 '11 at 12:53

3 Answers3

30

I have modified the code to include some checks:

public class Laj {

  private static void printLines(String name, InputStream ins) throws Exception {
    String line = null;
    BufferedReader in = new BufferedReader(
        new InputStreamReader(ins));
    while ((line = in.readLine()) != null) {
        System.out.println(name + " " + line);
    }
  }

  private static void runProcess(String command) throws Exception {
    Process pro = Runtime.getRuntime().exec(command);
    printLines(command + " stdout:", pro.getInputStream());
    printLines(command + " stderr:", pro.getErrorStream());
    pro.waitFor();
    System.out.println(command + " exitValue() " + pro.exitValue());
  }

  public static void main(String[] args) {
    try {
      runProcess("javac Main.java");
      runProcess("java Main");
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

Here is the Main.java:

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

When everything is fine, it just works:

alqualos@ubuntu:~/tmp$ java Laj
javac Main.java exitValue() 0
java Main stdout: ok
java Main exitValue() 0

Now, for example, if I have some error in Main.java:

alqualos@ubuntu:~/tmp$ java Laj
javac Main.java stderr: Main.java:3: package Systems does not exist
javac Main.java stderr:     Systems.out.println("ok");
javac Main.java stderr:            ^
javac Main.java stderr: 1 error
javac Main.java exitValue() 1
java Main stdout: ok
java Main exitValue() 0

It still prints "ok" because the previously compiled Main.class is still there, but at least you can see what exactly is happening when your processes are running.

Sergei Tachenov
  • 24,345
  • 8
  • 57
  • 73
0

I have added the condition in Laj class main function to check for compilation process has completed successfully or not..

public class Laj {

  private static void printLines(String name, InputStream ins) throws Exception {
    String line = null;
    BufferedReader in = new BufferedReader(
        new InputStreamReader(ins));
    while ((line = in.readLine()) != null) {
        System.out.println(name + " " + line);
    }
  }

  private static int runProcess(String command) throws Exception {
    Process pro = Runtime.getRuntime().exec(command);
    printLines(command + " stdout:", pro.getInputStream());
    printLines(command + " stderr:", pro.getErrorStream());
    pro.waitFor();
   // System.out.println(command + " exitValue() " + pro.exitValue());
    return pro.exitValue();
  }

  public static void main(String[] args) {
    try {
    int k =  runProcess("javac Main.java");
    if (k==0)
    k=runProcess("java Main");

    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}
0

You also need to

pro2.waitFor();

because executing that process will take some time and you can't take the exitValue() before the process has finished.

Confusion
  • 16,256
  • 8
  • 46
  • 71
  • I did this bu this also don't give any answer –  Jan 30 '11 at 11:54
  • @hilal, you actually need to do it after your last loop. You read process'es output while it's running, that's okay, but you can access exitValue() only after it has finished. – Sergei Tachenov Jan 30 '11 at 12:08
  • @hilal, your code from the first edition worked fine for me with no changes. I'll post the code with checks, though. – Sergei Tachenov Jan 30 '11 at 12:49