How to Compile & Run Java Program in Another Java Program

Running a java program from another java program

It is a bit strange but you can run the second program without forking it. Just calling the main method in it. So forget the runtime section and do this:

sam2.main(new String[0]);

Of course this way you must compile sam2 at compile time

Compile and run a Java program from another Java program

The Problem here is you are passing argument

./Main.java

instead, you should pass Main.java as an argument else you need to change your getProgramName() method to return the Class name correctly.

Which will let you compile the program perfectly with javac command but problem happens when you need to run the program because that command should be

java Main

whereas you are trying to execute

java ./Main

how to compile & run java program in another java program?

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.

CodeCompiler - Compile and Run Java Program from another Java Program

Since Java 1.6, Java has had a programmatic API to access the Java compiler without using a subprocess. As a starting point, see the documentation for the JavaCompiler class.

How Do I Compile/Run a java program from a Java Program (Input failure?)

Your main issue is understanding input and output streams.

Every process has three standard streams: standard input, standard output and standard error.

When you normally run a program from a command shell, be it Windows CMD or Linux terminal/console, the standard input is attached to the terminal's input stream, and the standard output and error to the console output.

When you run a process from within Java, especially when you use Runtime.exec rather than use a ProcessBuilder, the standard streams are piped from and two the calling program.

What you type into your "front" program doesn't automatically go to the "back" program. The "back" program calls nextLine on a scanner on System.in. Its System.in is redirected to the "front" program through Process.getOutputStream(). It is waiting for something to come through from that pipe. But your "front" program doesn't write anything to that stream. The only streams it has taken care of are the standard output and standard error - the output from the "back" program which is input from the point of view of the "front" program.

So the "back" program will sit and wait and do nothing. And your "front" program at this stage is trying to read its output. It will not stop reading it until the "back" program terminates or closes its standard output. Which of course it doesn't do.

So the two processes are deadlocked. Each of them is waiting for something from the other process.

In fact, there is another possible problem with the way you handle your streams. For example, if the program has errors, those errors will be placed in the standard error stream. If the program terminates, good. But if not, you'll never get to reading the standard error, because you'll still be endlessly waiting for the "standard output" from that program, which may not exist at all.


A possible solution to all this is to have separate threads handling each of the streams.

  • One thread will need to read the console input ("front" program System.in), and pass anything it reads to the getOutputStream() (standard input of "back" program).
  • One thread will need to read the "back" program's standard output (getInputStream()), and send everything to its own System.out.
  • One thread will need to do the same for the error stream and System.err.

But the complication is that when the "back" program terminates, you need to have those threads stop, so that you can read your own System.in again and run another command. The output-handling threads are relatively easy - when the process terminates, they will see "end of file" and they can terminate then. But the "input" reading thread will need to have a mechanism that interrupts it when the "back" program terminated.

BTW, if you use ProcessBuilder to build your process, you'll have better control of the redirection of your input and output. You could let your program write its output and error messages directly to console. You'll still need to design the input properly - lines that are intended for the "front" program should not be consumed by mistake by the "back" program, so you can't do without redirection for input.

How do I run a Java program from the command line on Windows?

Source: javaindos.

Let's say your file is in C:\mywork\

Run Command Prompt

C:\> cd \mywork

This makes C:\mywork the current directory.

C:\mywork> dir

This displays the directory contents. You should see
filenamehere.java among the files.

C:\mywork> set path=%path%;C:\Program Files\Java\jdk1.5.0_09\bin

This tells the system where to find JDK programs.

C:\mywork> javac filenamehere.java

This runs javac.exe, the compiler. You should see nothing but the
next system prompt...

C:\mywork> dir

javac has created the filenamehere.class file. You should see
filenamehere.java and filenamehere.class among the files.

C:\mywork> java filenamehere

This runs the Java interpreter. You should then see your program
output.

If the system cannot find javac, check the set path command. If javac
runs but you get errors, check your Java text. If the program
compiles but you get an exception, check the spelling and
capitalization in the file name and the class name and the java
HelloWorld command. Java is case-sensitive!



Related Topics



Leave a reply



Submit