我正在为我的大学开发Tomcat WebApp,使学生能够编译他们的Java代码并查看跟踪。我正在RHEL7 VM上安装它。但是当我测试编译功能(这个没有被我实现)时,我提供的方法会返回:
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
变量的内容作为其代码提交的结果。
有趣的是,我设法在className.class
目录中获取workingDir
,但我一直在上面的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;
}
}
答案 0 :(得分:0)
似乎您正在使用的用户没有写入目标文件夹的权限。 workingDir的权限是什么?
有趣的是,我设法在workingDir目录中获取className.class,但我不断从上面的for循环中获得该错误。问题可能是compiler.getTask(...)。call()?我的意思是也许compiler.run能够正确生成.class但是compile.getTask(...)。call()试图在其他地方编写.class我没有权限写入。< / p>
为了验证这是否属实,您可以创建一个具有开放权限的文件夹并尝试。 例如,您可以尝试使用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;
}
}
有一些变化,但结果应该是相同的。 我注意到了&#34;路径&#34;在
中指定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
和&#34;文件&#34;?
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