how to compile & run java program in another java program? [duplicate]
Asked Answered
H

3

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 ?

Hypochondrium answered 30/1, 2011 at 11:41 Comment(13)
Looks like you're looking for docs.codehaus.org/display/JANINO/Home ;) .Calvados
@Calvados it is just java code example. I will generalize it with c/c++ code and ohtersHypochondrium
Aren't you supposed to use Process.getOutputStream?Camara
What are the exitValue() 's of the processes? What do they output in ErrorStreams?Hartebeest
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.Equality
@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.Equality
@Sergey I just run this code in my netbeans projectHypochondrium
@hilal, disregard my previous comment. I missed that you call exitValue(). You can't do this before the process is finished. Confusion is right.Equality
@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).Equality
@Segey thanks for your comment. I think it is related to my classpath but I can't solve this problemHypochondrium
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 MainHartebeest
@hilal, I don't think classpath has anything to do with it. I'd suspect PATH instead.Equality
@hilal, sorry, PATH has nothing to do with it. If one of the commands was unavailable, it would break with an IOException.Equality
E
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.

Equality answered 30/1, 2011 at 13:5 Comment(4)
+1. I put these two files in same package. It was my error. Thanks SergeyHypochondrium
@Addy, then you need to use getOutputStream() on the second process to feed the process the data it needs. Or just close that stream so the process gets EOF immediately.Equality
how can we pass argument in this?Amal
When i try to run both commands using && like this... javac Main.java && java Main -> it fails ... Can you help @sergeyManvil
E
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.

Execrative answered 30/1, 2011 at 11:53 Comment(3)
I did this bu this also don't give any answerHypochondrium
@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.Equality
@hilal, your code from the first edition worked fine for me with no changes. I'll post the code with checks, though.Equality
M
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();
    }
  }
}
Matteo answered 2/4, 2014 at 16:19 Comment(1)
the answer, care to further clarify?Heliotaxis

© 2022 - 2024 — McMap. All rights reserved.