When reading the answer to this question, I was wondering how Java7 bootstrap knows about the presence of public static void main(String[] args)
method, without running the static initializers? I have some assumptions on this topic, but some of them is obviously wrong:
- Java Bootstrap is running in JVM, so it can only use standard JVM features (no native features) - the called class must be on CLASSPATH, for example
- The standard JVM classloading is done via the normal classloading mechanism (I know it has several steps, I've been playing with classloaders several times)
- After the class has been resolved (linked), the Class initialization is run immediately (including initializing static attributes and running static initializers)
- There is no way to part the previous two steps
My questions are:
- Who calls the class initializers and in what phase? (what happens before, and what after?)
- Why does the bootstrap behave differently compared to the "normal" classloading? Are there more differences over this?
- Bonus question: Which of my assumptions is wrong?
To summarize the referred question: if you run a Java main class (from Java7 command line), it will check the presence of the main()
method, without running the static initializers. In Java6 it behaves differently.
It is possible to load a class without linking it: the launcher in Java 8 loads the main class by calling the loadClass method on the classloader, which does not link the class or run any of its static methods.
See http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/sun/launcher/LauncherHelper.java#l495 and java.c#l1221 for the code that loads the main class in Java 8.
The Java 6 launcher uses the FindClass JNI method to load the main class: I'm guessing that this accounts for the difference in behaviour. See jdk6/jdk6/jdk/file/814bf0775b52/src/share/bin/java.c#l1387
FindClass does initialize the class, at least on Java 6: the implementation in jdk6/jdk6/hotspot/file/91e5cc5d33b9/src/share/vm/prims/jni.cpp
result = find_class_from_class_loader(env, sym, true, loader,
protection_domain, true, thread);
calls, in jdk6/jdk6/hotspot/file/91e5cc5d33b9/src/share/vm/prims/jvm_misc.hpp,
jclass find_class_from_class_loader(JNIEnv* env, Symbol* name, jboolean init, Handle loader, Handle protection_domain, jboolean throwError, TRAPS);
with init as true
来源:https://stackoverflow.com/questions/17890723/java7-bootstrap-checking-class-without-loading