[英]Java Compiler keeps saying “error while writing className: className.class (Permission denied)”
I'm working on a Tomcat WebApp for my university which enables students to compile their Java codes and see the trace. 我正在为我的大学开发Tomcat WebApp,使学生可以编译Java代码并查看跟踪。 I'm installing it on a RHEL7 VM. 我正在RHEL7 VM上安装它。 But when I test the compilation function (this one is not implemented by me), the method I'm providing returns this: 但是,当我测试编译功能(这个功能不是我自己实现的)时,我提供的方法将返回以下内容:
error while writing className: className.class (Permission denied)
Error on line 1 in className.java
I'll show you the method I think is generating this: 我将向您展示我认为生成此方法的方法:
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;
}
Students will see the content of that diagn
variable as a result for their code submission. 学生将在提交代码时看到该diagn
变量的内容。
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. 一个有趣的事实是,我设法在workingDir
目录中获取了className.class
,但是我一直从上述for
循环中获取该错误。 Could the problem be compiler.getTask(...).call()
? 问题可能是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. 我的意思是也许compiler.run
能够正确生成.class,但是compile.getTask compiler.getTask(...).call()
试图将.class写入其他我没有写权限的地方。
PS This is a pretty legacy code so please be merciful with it. PS这是一个非常漂亮的遗留代码,因此请多加注意。 :) :)
As asked by @Alexander, this is the content of the Java file: 如@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;
}
}
Seems like the user you are using doesn't have the permissions to write to the destination folder. 似乎您正在使用的用户没有写目标文件夹的权限。 What are the permissions of the workingDir? 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. 有趣的事实是,我设法在workingDir目录中获取了className.class,但是我一直从上述for循环中获取该错误。 Could the problem be the compiler.getTask(...).call()? 问题可能出在editor.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. 我的意思是也许editor.run能够正确生成.class,但是compile.getTask(...)。call()试图将.class写入其他我没有写权限的地方。
In order to verify if this is true, you could create a folder with open permissions and try. 为了验证是否为真,您可以创建一个具有打开权限的文件夹并尝试。 For example, you could try using as workingDir = /tmp and check what happens. 例如,您可以尝试使用as workingDir = / tmp并检查会发生什么。
EDIT 编辑
I tried to replicate your code: 我试图复制您的代码:
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;
}
}
with Foo.java 与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;
}
}
There are some changes, but the result should be the same. 进行了一些更改,但结果应该相同。 I noticed that the "path" is specified in 我注意到“路径”在
File workingDir
that will be use in 将用于
compiler.run(null, null, null, workingDir.getAbsolutePath() + File.separator + "Foo.java");
and in 和在
JavaFileObject file = new JavaSourceFromString(javaFileName, javaCode);
Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(file);
that in my example: 在我的示例中:
Iterable<? extends JavaFileObject> compilationUnits = fileManager
.getJavaFileObjectsFromStrings(Arrays.asList(System.getProperty("user.dir") + "/src/main/java/Foo.java"));
What contains yours 什么包含您的
workingDir
and "file"? 和“文件”?
JavaFileObject file = new JavaSourceFromString(javaFileName, javaCode);
In my case, are the same. 就我而言,都是一样的。
I tried to execute the code with different users, and if I use an user that isn't able to write in this folder I obtain 我尝试与其他用户执行代码,如果我使用的用户无法在此文件夹中写入,则将获得
/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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.