Java编译器一直说“编写className时出错:className.class(权限被拒绝)”

时间:2017-09-03 11:47:39

标签: java web-applications compiler-errors compiler-warnings rhel

我正在为我的大学开发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;
    }
}

1 个答案:

答案 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