Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't ant run Main when the JVM can

Tags:

java

jvm

ant

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

Starting the program through the shell: java Main works as expected but starting the program through ant:

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

causes this error:

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

JLS Section 12.3.3 Resolution of Symbolic References:

IllegalAccessError: A symbolic reference has been encountered that specifies a use or assignment of a field, or invocation of a method, or creation of an instance of a class, to which the code containing the reference does not have access because the field or method was declared private, protected, or default access (not public), or because the class was not declared public.

So org.apache.tools.ant.taskdefs.ExecuteJava can't execute the method because it's enclosing class is private, but if I start the jvm pointed at a .class with a private method, it doesn't go through the same security mechanism?

This question is similar but I still don't understand

like image 643
xst Avatar asked Aug 03 '12 12:08

xst


Video Answer


1 Answers

The answer is all in the question you linked to. When you run it through the JVM it has access to absolutely everything regardless of access level. When you run it through ant, which itself is another java program, it has to obey by the same rules as any other program - which means that it cannot see your main method.

If you declare your class as public class Main the problem should go away.

As to why the jvm has made this decision to allow access to private classes when starting is another matter indeed. As per the specification

12.1.4 Invoke Test.main

Finally, after completion of the initialization for class Test (during which other consequential loading, linking, and initializing may have occurred), the method main of Test is invoked. The method main must be declared public, static, and void. It must accept a single argument that is an array of strings. This method can be declared as either

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

This specifically states that the method must be public but says nothing about the class in questions, which why it works when you invoke main through the VM directly.

like image 100
Dervall Avatar answered Oct 19 '22 00:10

Dervall