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

时间:2012-08-03 12:22:44

标签: java ant jvm

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:遇到符号引用   指定字段的使用或赋值,或者调用a   方法,或创建一个类的实例,代码   包含引用没有访问权限,因为该字段或   方法被声明为私有,受保护或默认访问(不是   公共),或因为该课程未被公开宣布。

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

This问题类似,但我仍然不明白

3 个答案:

答案 0 :(得分:10)

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

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

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

  

12.1.4调用Test.main

     

最后,完成类Test的初始化(期间)   其他相应的加载,链接和初始化可能有   发生了),调用了Test的方法main。方法必须是   声明公开,静态和无效。它必须接受一个论点   这是一个字符串数组。此方法可以声明为

     

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

这明确指出方法必须是public,但在问题中没有说明类,这就是当你通过VM直接调用main时它的工作原理。

答案 1 :(得分:0)

尝试将public修饰符添加到类中:

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

答案 2 :(得分:0)

使用public access-modifier

<强>例如

public class Main {
    public static void main(String[] args) {
        // Your code..
    }
}