简体   繁体   English

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

[英]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.

相关问题 Java 中的“ClassName.class”是否与 Kotlin 中的“[ClassName::class]”相同? - is 'ClassName.class' in Java same as '[ClassName::class]' in Kotlin? Android中classname.class指的是什么? - What does classname.class refer to in Android? 使用“ClassName.class;”创建 object 有什么区别? 和“新的类名();” 在 java 中? - What are the differences between object creation using “ClassName.class;” and “new ClassName();” in java? Intellij用ClassName.class替换getClass() - Intellij replace getClass() with ClassName.class classname.class返回什么? - What does classname.class return? 在Java中,在ClassName.class而不是类的实例上进行同步可能带来的副作用? - In java, possible side effects of synchronizing on ClassName.class instead of on instance of a class? synchronized(this)和synchronized(ClassName.class)有什么区别? - What is the difference between synchronized(this) and synchronized(ClassName.class)? 我们为什么要写Synchronized(ClassName.class) - Why do we write Synchronized(ClassName.class) ClassObject.getClass,ClassName.class和Class.forName(“ClassName”)之间的区别 - Distinction between ClassObject.getClass,ClassName.class and Class.forName(“ClassName”) 返回 <ClassName> .class而不是简单 <ClassName> 在Java中? - Return <ClassName>.class instead of simply <ClassName> in Java?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM