First of all I have searched the forum and the web for 5 hours, but couldn't find out what my problem is so I'm hoping this isn't a duplicate.
I am using the Java ProcessBuilder to compile and run a Java Project. When I type
javac /Users/Katzenmeister/Desktop/Final/src/edu/kit/informatik/citationmanager/*.java
to my Terminal on MacOSX I can compile the whole folder without any errors.
In my Program I have the following
public class CompilerController {
private static File directory;
private static String mainClass;
private static boolean compiled = false;
public static void setDirectory(File directory) {
CompilerController.directory = directory;
}
public static void setMainClass(String mainClass) {
CompilerController.mainClass = mainClass;
}
private static void compile() {
ProcessBuilder pb = new ProcessBuilder("javac",directory.getAbsolutePath()+"/*.java");
pb.inheritIO();
try {
pb.start();
compiled = true;
} catch (IOException ex) {
System.out.println(ex);
}
}
private static String[] getSourcePath() {
String[] strArr = directory.toString().split("src");
strArr[0] += "src";
strArr[1] += mainClass;
return strArr;
}
private static void run() {
ProcessBuilder pb = new ProcessBuilder("java",getSourcePath()[0],getSourcePath()[1]);
try {
pb.start();
} catch(IOException ex) {
System.out.println(ex);
}
}
public static void compileRun() {
compile();
if (compiled) {
run();
}
}
}
In my JavaFX Controller class I get the directory by using a DirectoryChooser and passing the absolute path to the CompilerController using setDirectory().
When I run my program I get the following error:
javac: file not found: /Users/Katzenmeister/Desktop/Final/src/edu/kit/informatik/citationmanager/*.java
Usage: javac <options> <source files>
use -help for a list of possible options
Which is as far as I can tell the same thing I got working on my Terminal. I have only been coding for 6 Months now so I lack knowledge, but I'm assuming this is due to the JVM Runtime Directory probably. Any help is very welcome. Here are some of the forum links that I have already checked for reference:
ProcessBuilder can't find file?!
Run a .java file using ProcessBuilder
Compile and Run Java Program from another Java Program
ProcessBuilder can't find file?!
P.S: This is my first question on the forum. I tried my best to fit the etiquette, if I have done anything wrong please tell me so I can edit my question.
EDIT: I got the code to work as follows for anyone who might have a similar problem
private static void compile() {
ArrayList<String> files = new ArrayList<>();
files.add("javac");
files.add("-sourcepath");
files.add("./*");
try {
for (File file : directory.listFiles()) {
if (!file.isHidden()) {
files.add(file.getName());
}
}
} catch(NullPointerException ex) {}
pb.directory(new File(directory.getAbsolutePath()));
pb.command(files);
pb.inheritIO();
try {
synchronized (processLock) {
Process pr = pb.start();
int i = pr.waitFor();
}
compiled = true;
} catch (IOException ex) {
System.out.println(ex);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
*
is processed differently in the shell vs in ProcessBuilder
: it is expanded before being passed to javac
in the shell, but it is passed literally in the ProcessBuilder
command.
You can see this if you add echo
before the command in the shell:
echo javac /Users/whatever/*.java
will print out something like:
javac /Users/whatever/Foo.java /Users/whatever/Bar.java
When you are invoking ProcessBuilder
like that, you are doing the equivalent of single-quoting the path in the shell, like this:
javac '/Users/whatever/*.java'
which suppresses glob expansion, so javac
receives /Users/whatever/*.java
, as you can see if you add echo
to the front:
echo javac '/Users/whatever/*.java'
prints
javac /Users/whatever/*.java
You need to expand the glob yourself, e.g. use new File("/your/directory").listFiles()
, and pass all the files to the ProcessBuilder
explicitly.