0

I'm running into a pesky little error and I'm not sure how to solve it. What I'm trying to do is pretty simple: Run an external .java file using ProcessBuilder. Just like that tittle suggests.

The problem is that the file that runs and creates this ProcessBuilder is in a different directory than the other file I want to run.

What I'm trying to do to get around this is:

String command[] = {"javac",JAVA_FILE_LOCATION};
ProcessBuilder processBuilder = new ProcessBuilder("cd");
Process process0 = processBuilder.start();

to reset the directory and

processBuilder = new ProcessBuilder(command);
Process process = processBuilder.start();

to compile the other file

if( process.getErrorStream().read() != -1 ){
    print("Compilation Errors",process.getErrorStream());
}

and just some error handling here. However it doesn't get past this error handle part. I can't figure out the proper way of doing this. Here's the error message:

my_PC:Processes user$ java -jar process.jar
************* Compilation Errors***********************
avac: file not found: /Users/Desktop/Piano.java
Usage: javac <options> <source files>
use -help for a list of possible options
Exception in thread "main" java.lang.IllegalThreadStateException: process hasn't exited
at java.lang.UNIXProcess.exitValue(UNIXProcess.java:423)
at my.package.address.Main.main(Main.java:28)

Does anyone know what I'm doing wrong ? Also I can post the whole code if needed, but I figured it's not really relevant here.

UPDATED: added my code

package some.random.package;

import java.io.*;

public class Main {
/**
* Provide absolute JAVA file path
*/
private static final String JAVA_FILE_LOCATION = "/Users/Desktop/piano.java";

    public static void main(String args[]) throws IOException
    {
        String command[] = {"javac",JAVA_FILE_LOCATION};
        ProcessBuilder processBuilder = new ProcessBuilder(command).directory(new File("/Users/Desktop/"));
        Process process = processBuilder.start();
        if( process.getErrorStream().read() != -1 ){
            print("Compilation Errors",process.getErrorStream());
        }
        /**
        * check if compile is successful
        * 0 => successful
        */
        if( process.exitValue() == 0 )
        {
            process = new ProcessBuilder(new String[]{"java","piano"}).directory(new File("/Users/Desktop/")).start();
            if( process.getErrorStream().read() != -1 )
                print("Errors ",process.getErrorStream());
            else
                print("Output ",process.getInputStream());

            /**
            * Check if RuntimeException or Errors encounter during execution then print errors on console
            * Otherwise print Output
            */
        }
    }
    private static void print(String status,InputStream input) throws IOException
    {
        BufferedReader in = new BufferedReader(new InputStreamReader(input));
        System.out.println("************* "+status+"***********************");
        String line = null;
        while((line = in.readLine()) != null ){
        System.out.println(line);
      }
    in.close();
    }
}

1 Answer 1

1

The cd command you execute with the first ProcessBuilder affects only that child process, it does not change the working directory of the main executing program. When you run the second ProcessBuilder, it will have the working directory as the main program, completely unaffected by the cd executed by the previous ProcessBuilder.

To execute a program from a different directory, use the directory(...) method of ProcessBuilder:

String command[] = {"javac", JAVA_FILE_LOCATION};
ProcessBuilder processBuilder = new ProcessBuilder(command).directory(new File("path/to/dir"));
Process process0 = processBuilder.start();

Btw, the path "/Users/Desktop/piano.java" looks very strange. The path to a user's desktop on a Mac is usually /Users/username/Desktop, so the path in your code implies that your username is "Desktop", which is very unusual.

And, to make it easier to work with the program, I suggest to put the base directory path (/Users/username/Desktop) in a variable, rather then hardcoding it at multiple places. That way it will be easier to make changes, no need to edit at multiple places.

Sign up to request clarification or add additional context in comments.

8 Comments

I see, that explains a lot. So if I wanted to then run that file after compiling it. It would just be something like process = new ProcessBuilder(new String[]{"java","Piano"}).directory(new File("Users/Desktop/")).start();
@MarcoNeves exactly
Alright, now I'm just getting "No such file or directory". This is probably a dumb question but does the file name have to be included in the path ? My path is just /Users/Desktop and the file "piano.java" is just there by itself. No package statements or anything.
@MarcoNeves If you see only Piano.java (no Piano.class) then it looks like the compile step didn't work. If you run javac Piano.java in /Users/Desktop in a terminal, not by your program, does it actually work?
Yes, javac Piano.java works and java Piano runs it as it's supposed to.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.