javac:在 ProcessBuilder 中找不到文件。命令在 ProcessBuilder 参数中分开
javac: file not found in ProcessBuilder. Commands are separated in ProcessBuilder arguments
首先,我已经在论坛和网络上搜索了 5 个小时,但找不到我的问题所在,所以我希望这不是重复的。
我正在使用 Java ProcessBuilder 编译和 运行 一个 Java 项目。当我输入
javac /Users/Katzenmeister/Desktop/Final/src/edu/kit/informatik/citationmanager/*.java
到我在 MacOSX 上的终端,我可以毫无错误地编译整个文件夹。
在我的程序中我有以下内容
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();
}
}
}
在我的 JavaFX 控制器 class 中,我通过使用 DirectoryChooser 获取目录并使用 setDirectory() 将绝对路径传递给 CompilerController。
当我 运行 我的程序出现以下错误:
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
据我所知,这与我在终端上工作的情况相同。我现在只编码了 6 个月,所以我缺乏知识,但我假设这可能是由于 JVM 运行时目录。非常欢迎任何帮助。以下是我已经检查过以供参考的一些论坛链接:
ProcessBuilder can't find file?!
Run a .java file using ProcessBuilder
How to run a Java program using ProcessBuilder inside the other Java program. (with -cp and -Xbootclasspath commands)
Compile and Run Java Program from another Java Program
ProcessBuilder can't find file?!
P.S: 这是我在论坛上的第一个问题。我尽力符合礼仪,如果我做错了什么,请告诉我,以便我可以编辑我的问题。
编辑:对于可能有类似问题的任何人,我得到的代码可以按如下方式工作
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();
}
}
*
在 shell 和 ProcessBuilder
中的处理方式不同:它在被传递给 shell 中的 javac
之前被扩展,但是它在 ProcessBuilder
命令中逐字传递。
如果在shell中的命令前加上echo
就可以看到这个:
echo javac /Users/whatever/*.java
将打印出如下内容:
javac /Users/whatever/Foo.java /Users/whatever/Bar.java
当您像那样调用 ProcessBuilder
时,您相当于在 shell 中单引号路径,如下所示:
javac '/Users/whatever/*.java'
抑制了全局扩展,所以javac
收到/Users/whatever/*.java
,如果你在前面添加echo
就可以看到:
echo javac '/Users/whatever/*.java'
打印
javac /Users/whatever/*.java
您需要自己扩展 glob,例如使用 new File("/your/directory").listFiles()
,并将所有文件显式传递给 ProcessBuilder
。
首先,我已经在论坛和网络上搜索了 5 个小时,但找不到我的问题所在,所以我希望这不是重复的。
我正在使用 Java ProcessBuilder 编译和 运行 一个 Java 项目。当我输入
javac /Users/Katzenmeister/Desktop/Final/src/edu/kit/informatik/citationmanager/*.java
到我在 MacOSX 上的终端,我可以毫无错误地编译整个文件夹。
在我的程序中我有以下内容
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();
}
}
}
在我的 JavaFX 控制器 class 中,我通过使用 DirectoryChooser 获取目录并使用 setDirectory() 将绝对路径传递给 CompilerController。
当我 运行 我的程序出现以下错误:
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
据我所知,这与我在终端上工作的情况相同。我现在只编码了 6 个月,所以我缺乏知识,但我假设这可能是由于 JVM 运行时目录。非常欢迎任何帮助。以下是我已经检查过以供参考的一些论坛链接:
ProcessBuilder can't find file?!
Run a .java file using ProcessBuilder
How to run a Java program using ProcessBuilder inside the other Java program. (with -cp and -Xbootclasspath commands)
Compile and Run Java Program from another Java Program
ProcessBuilder can't find file?!
P.S: 这是我在论坛上的第一个问题。我尽力符合礼仪,如果我做错了什么,请告诉我,以便我可以编辑我的问题。
编辑:对于可能有类似问题的任何人,我得到的代码可以按如下方式工作
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();
}
}
*
在 shell 和 ProcessBuilder
中的处理方式不同:它在被传递给 shell 中的 javac
之前被扩展,但是它在 ProcessBuilder
命令中逐字传递。
如果在shell中的命令前加上echo
就可以看到这个:
echo javac /Users/whatever/*.java
将打印出如下内容:
javac /Users/whatever/Foo.java /Users/whatever/Bar.java
当您像那样调用 ProcessBuilder
时,您相当于在 shell 中单引号路径,如下所示:
javac '/Users/whatever/*.java'
抑制了全局扩展,所以javac
收到/Users/whatever/*.java
,如果你在前面添加echo
就可以看到:
echo javac '/Users/whatever/*.java'
打印
javac /Users/whatever/*.java
您需要自己扩展 glob,例如使用 new File("/your/directory").listFiles()
,并将所有文件显式传递给 ProcessBuilder
。