7
class Main {
    public static void main(String[] args) {
        ....
    }
}

通过 shell 启动程序:java Main按预期工作,但通过 ant 启动程序:

<target name="run" depends="cmp">
    <java classname="Main" classpath="."/>
</target>`

导致此错误:

java.lang.IllegalAccessException: Class org.apache.tools.ant.taskdefs.ExecuteJava can not access a member of class Main with modifiers "public static"

JLS 第 12.3.3 节符号引用的解析:

IllegalAccessError:遇到了一个符号引用,它指定了一个字段的使用或分配,或方法的调用,或类的实例的创建,包含该引用的代码无权访问,因为该字段或方法是声明为私有、受保护或默认访问(非公共),或者因为该类未声明为公共。

所以org.apache.tools.ant.taskdefs.ExecuteJava无法执行该方法,因为它的封闭类是私有的,但是如果我用私有方法启动指向 .class 的 jvm,它不会通过相同的安全机制?

这个问题类似,但我还是不明白

4

3 回答 3

10

答案都在您链接到的问题中。当您通过 JVM 运行它时,无论访问级别如何,它都可以访问所有内容。当你通过 ant 运行它时,它本身就是另一个 java 程序,它必须遵守与任何其他程序相同的规则——这意味着它看不到你的 main 方法。

如果您将班级声明为public class Main问题应该消失。

至于为什么 jvm 决定在启动时允许访问私有类确实是另一回事。根据规范

12.1.4 调用Test.main

最后,在完成类Test的初始化之后(在此期间可能发生了其他相应的加载、链接和初始化),调用Test的main方法。方法 main 必须声明为 public、static 和 void。它必须接受一个作为字符串数组的参数。此方法可以声明为

public static void main(String[] args) 或 public static void main(String...args)

这特别指出该方法必须是public,但对所讨论的类只字未提,这就是为什么当您直接通过 VM 调用 main 时它起作用的原因。

于 2012-08-03T12:28:38.287 回答
0

使用public access-modifier.

例如:

public class Main {
    public static void main(String[] args) {
        // Your code..
    }
}
于 2012-08-03T12:37:13.340 回答
0

尝试将 public 修饰符添加到类中,如下所示:

public class Main {
    public static void main(String[] args) {
        ....
    }
}
于 2012-08-03T12:28:38.050 回答