Java 编译器一直说 "error while writing className: className.class (Permission denied)"
Java Compiler keeps saying "error while writing className: className.class (Permission denied)"
我正在为我的大学开发一个 Tomcat Web 应用程序,它使学生能够编译他们的 Java 代码并查看跟踪。我正在将它安装在 RHEL7 VM 上。但是当我测试编译功能时(这个不是我实现的),我提供的方法returns this:
error while writing className: className.class (Permission denied)
Error on line 1 in className.java
我将向您展示我认为生成此内容的方法:
public String compileJavaCode(String javaCode, String javaFileName, File workingDir) throws IOException, TimeoutException{
javax.tools.JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
this.createJavaFile(javaCode, javaFileName, workingDir);
JavaFileObject file = new JavaSourceFromString(javaFileName, javaCode);
Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(file);
compiler.getTask(null, fileManager, diagnostics, null, null, compilationUnits).call();
String diagn = "";
for ( Diagnostic<? extends JavaFileObject> diagnostic : diagnostics.getDiagnostics()){
diagn+=diagnostic.getMessage(null)+"\n";//E.g. cannot find symbol symbol: variable variablename
diagn+="Error on line "+Long.toString(diagnostic.getLineNumber())+" in "+diagnostic.getSource().toUri();//E.g. Error on line 22 in ClassName.java
}
fileManager.close();
compiler.run(null, null, null, workingDir.getAbsolutePath()+File.separator+javaFileName);
return diagn;
}
学生将在提交代码时看到 diagn
变量的内容。
有趣的是,我设法在 workingDir
目录中获取了 className.class
,但我不断从上面的 for
循环中收到该错误。问题可能是compiler.getTask(...).call()
?我的意思是也许 compiler.run
能够正确生成 .class 但 compiler.getTask(...).call()
正试图将 .class 写入其他我没有写入权限的地方。
P.S。这是一个非常遗留的代码,所以请对它手下留情。 :)
正如@Alexander 所问,这是 Java 文件的内容:
public class Sommatore {
public int somma(int i, int j) {
return i+j;
}
public int differenza(int i, int j) {
return i-j;
}
}
您使用的用户似乎没有写入目标文件夹的权限。 workingDir 的权限是什么?
Fun fact is that i manage to get the className.class in the workingDir directory but i keep getting that error from the for cycle above. Could the problem be the compiler.getTask(...).call()? I mean maybe compiler.run is able to generate the .class correctly but the compiler.getTask(...).call() is trying to write the .class somewhere else i don't have permission to write in.
为了验证是否属实,您可以新建一个具有开放权限的文件夹试试。
例如,您可以尝试使用 as workingDir = /tmp 并检查会发生什么。
编辑
我试图复制你的代码:
public class JavaCompiler {
public static void main(String args[]) throws IOException, TimeoutException {
File dir = new File(System.getProperty("user.dir") + "/src/main/java/");
System.out.println(compileJavaCode(dir));
}
public static String compileJavaCode(File workingDir) throws IOException, TimeoutException {
javax.tools.JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
// this.createJavaFile(javaCode, javaFileName, workingDir);
// JavaFileObject file = new JavaSourceFromString(javaFileName, javaCode);
Iterable<? extends JavaFileObject> compilationUnits = fileManager
.getJavaFileObjectsFromStrings(Arrays.asList(System.getProperty("user.dir") + "/src/main/java/Foo.java"));
// Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(file);
compiler.getTask(null, fileManager, diagnostics, null, null, compilationUnits).call();
String diagn = "";
for (Diagnostic<? extends JavaFileObject> diagnostic : diagnostics.getDiagnostics()) {
diagn += diagnostic.getMessage(null) + "\n";//E.g. cannot find symbol symbol: variable variablename
diagn += "Error on line " + Long.toString(diagnostic.getLineNumber()) + " in " + diagnostic.getSource().toUri();//E.g. Error on line 22 in ClassName.java
}
fileManager.close();
compiler.run(null, null, null, workingDir.getAbsolutePath() + File.separator + "Foo.java");
return diagn;
}
}
与Foo.java
public class Foo {
public int somma(int i, int j) {
return i+j;
}
public int differenza(int i, int j) {
return i-j;
}
}
有一些变化,但结果应该是一样的。
我注意到 "path" 是在
中指定的
File workingDir
将在
中使用
compiler.run(null, null, null, workingDir.getAbsolutePath() + File.separator + "Foo.java");
并在
JavaFileObject file = new JavaSourceFromString(javaFileName, javaCode);
Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(file);
在我的示例中:
Iterable<? extends JavaFileObject> compilationUnits = fileManager
.getJavaFileObjectsFromStrings(Arrays.asList(System.getProperty("user.dir") + "/src/main/java/Foo.java"));
包含你的内容
workingDir
和"file"?
JavaFileObject file = new JavaSourceFromString(javaFileName, javaCode);
在我的情况下,都是一样的。
我尝试用不同的用户执行代码,如果我使用无法写入此文件夹的用户,我会得到
/tmp/testSO/src/main/java/Foo.java:5: error: error while writing Foo: /tmp/testSO/src/main/java/Foo.class (Permission denied)
public class Foo {
^
1 error
error while writing Foo: /tmp/testSO/src/main/java/Foo.class (Permission denied)
Error on line 5 in file:/tmp/testSO/src/main/java/Foo.java
我正在为我的大学开发一个 Tomcat Web 应用程序,它使学生能够编译他们的 Java 代码并查看跟踪。我正在将它安装在 RHEL7 VM 上。但是当我测试编译功能时(这个不是我实现的),我提供的方法returns this:
error while writing className: className.class (Permission denied)
Error on line 1 in className.java
我将向您展示我认为生成此内容的方法:
public String compileJavaCode(String javaCode, String javaFileName, File workingDir) throws IOException, TimeoutException{
javax.tools.JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
this.createJavaFile(javaCode, javaFileName, workingDir);
JavaFileObject file = new JavaSourceFromString(javaFileName, javaCode);
Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(file);
compiler.getTask(null, fileManager, diagnostics, null, null, compilationUnits).call();
String diagn = "";
for ( Diagnostic<? extends JavaFileObject> diagnostic : diagnostics.getDiagnostics()){
diagn+=diagnostic.getMessage(null)+"\n";//E.g. cannot find symbol symbol: variable variablename
diagn+="Error on line "+Long.toString(diagnostic.getLineNumber())+" in "+diagnostic.getSource().toUri();//E.g. Error on line 22 in ClassName.java
}
fileManager.close();
compiler.run(null, null, null, workingDir.getAbsolutePath()+File.separator+javaFileName);
return diagn;
}
学生将在提交代码时看到 diagn
变量的内容。
有趣的是,我设法在 workingDir
目录中获取了 className.class
,但我不断从上面的 for
循环中收到该错误。问题可能是compiler.getTask(...).call()
?我的意思是也许 compiler.run
能够正确生成 .class 但 compiler.getTask(...).call()
正试图将 .class 写入其他我没有写入权限的地方。
P.S。这是一个非常遗留的代码,所以请对它手下留情。 :)
正如@Alexander 所问,这是 Java 文件的内容:
public class Sommatore {
public int somma(int i, int j) {
return i+j;
}
public int differenza(int i, int j) {
return i-j;
}
}
您使用的用户似乎没有写入目标文件夹的权限。 workingDir 的权限是什么?
Fun fact is that i manage to get the className.class in the workingDir directory but i keep getting that error from the for cycle above. Could the problem be the compiler.getTask(...).call()? I mean maybe compiler.run is able to generate the .class correctly but the compiler.getTask(...).call() is trying to write the .class somewhere else i don't have permission to write in.
为了验证是否属实,您可以新建一个具有开放权限的文件夹试试。 例如,您可以尝试使用 as workingDir = /tmp 并检查会发生什么。
编辑
我试图复制你的代码:
public class JavaCompiler {
public static void main(String args[]) throws IOException, TimeoutException {
File dir = new File(System.getProperty("user.dir") + "/src/main/java/");
System.out.println(compileJavaCode(dir));
}
public static String compileJavaCode(File workingDir) throws IOException, TimeoutException {
javax.tools.JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
// this.createJavaFile(javaCode, javaFileName, workingDir);
// JavaFileObject file = new JavaSourceFromString(javaFileName, javaCode);
Iterable<? extends JavaFileObject> compilationUnits = fileManager
.getJavaFileObjectsFromStrings(Arrays.asList(System.getProperty("user.dir") + "/src/main/java/Foo.java"));
// Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(file);
compiler.getTask(null, fileManager, diagnostics, null, null, compilationUnits).call();
String diagn = "";
for (Diagnostic<? extends JavaFileObject> diagnostic : diagnostics.getDiagnostics()) {
diagn += diagnostic.getMessage(null) + "\n";//E.g. cannot find symbol symbol: variable variablename
diagn += "Error on line " + Long.toString(diagnostic.getLineNumber()) + " in " + diagnostic.getSource().toUri();//E.g. Error on line 22 in ClassName.java
}
fileManager.close();
compiler.run(null, null, null, workingDir.getAbsolutePath() + File.separator + "Foo.java");
return diagn;
}
}
与Foo.java
public class Foo {
public int somma(int i, int j) {
return i+j;
}
public int differenza(int i, int j) {
return i-j;
}
}
有一些变化,但结果应该是一样的。 我注意到 "path" 是在
中指定的File workingDir
将在
中使用compiler.run(null, null, null, workingDir.getAbsolutePath() + File.separator + "Foo.java");
并在
JavaFileObject file = new JavaSourceFromString(javaFileName, javaCode);
Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(file);
在我的示例中:
Iterable<? extends JavaFileObject> compilationUnits = fileManager
.getJavaFileObjectsFromStrings(Arrays.asList(System.getProperty("user.dir") + "/src/main/java/Foo.java"));
包含你的内容
workingDir
和"file"?
JavaFileObject file = new JavaSourceFromString(javaFileName, javaCode);
在我的情况下,都是一样的。
我尝试用不同的用户执行代码,如果我使用无法写入此文件夹的用户,我会得到
/tmp/testSO/src/main/java/Foo.java:5: error: error while writing Foo: /tmp/testSO/src/main/java/Foo.class (Permission denied)
public class Foo {
^
1 error
error while writing Foo: /tmp/testSO/src/main/java/Foo.class (Permission denied)
Error on line 5 in file:/tmp/testSO/src/main/java/Foo.java