为什么当JVM可以运行时,ant不能运行Main

xst*_*xst 7 java ant jvm

class Main {
    public static void main(String[] args) {
        ....
    }
}
Run Code Online (Sandbox Code Playgroud)

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

<target name="run" depends="cmp">
    <java classname="Main" classpath="."/>
</target>`
Run Code Online (Sandbox Code Playgroud)

导致此错误:

java.lang.IllegalAccessException: Class org.apache.tools.ant.taskdefs.ExecuteJava can not access a member of class Main with modifiers "public static"
Run Code Online (Sandbox Code Playgroud)

JLS第12.3.3节符号引用的解决方案:

IllegalAccessError:遇到符号引用,指定字段的使用或赋值,或方法的调用,或类的实例的创建,包含引用的代码无法访问该类,因为该字段或方法是声明私有,受保护或默认访问(非公开),或者因为该类未声明为public.

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

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

Der*_*all 10

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

如果你宣布你的班级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时它的工作原理.