It's OK to see the event twice. This means the class resolution happens twice in the context of different class loaders. First, it is resolved by the Bootstrap class loader, then by the System class loader - sun.misc.Launcher.AppClassLoader
.
The utility from this answer will shed light on the circumstances when such events happen.
Consider a simple example:
public class Test {
public void setThreadFactory(ThreadFactory factory) {
}
public static void main(String[] args) {
}
}
When the launcher looks for public static void main()
, it creates Method
objects for public methods, and this causes resolution of all classes in the signatures of such methods.
The first ClassLoad event:
Class loaded: java/util/concurrent/ThreadFactory
- ClassLoad(_jvmtiEnv*, JNIEnv_*, _jobject*, _jclass*) + 0x69
- JvmtiExport::post_class_load(JavaThread*, Klass*) + 0x15b
- SystemDictionary::define_instance_class(instanceKlassHandle, Thread*) + 0x3cc
- SystemDictionary::find_or_define_instance_class(Symbol*, Handle, instanceKlassHandle, Thread*) + 0x35d
- SystemDictionary::load_instance_class(Symbol*, Handle, Thread*) + 0x20c
- SystemDictionary::resolve_instance_class_or_null(Symbol*, Handle, Handle, Thread*) + 0x78c
- JVM_FindClassFromBootLoader + 0x22b
- Java_java_lang_ClassLoader_findBootstrapClass + 0x9b
* java/lang/ClassLoader.findBootstrapClass @ -1
* java/lang/ClassLoader.findBootstrapClassOrNull @ 12
* java/lang/ClassLoader.loadClass @ 48
* java/lang/ClassLoader.loadClass @ 38
* sun/misc/Launcher$AppClassLoader.loadClass @ 81
* java/lang/ClassLoader.loadClass @ 3
* java/lang/Class.getDeclaredMethods0 @ -1
* java/lang/Class.privateGetDeclaredMethods @ 37
* java/lang/Class.privateGetMethodRecursive @ 2
* java/lang/Class.getMethod0 @ 16
* java/lang/Class.getMethod @ 13
* sun/launcher/LauncherHelper.validateMainClass @ 12
* sun/launcher/LauncherHelper.checkAndLoadMain @ 214
The second one:
Class loaded: java/util/concurrent/ThreadFactory
- ClassLoad(_jvmtiEnv*, JNIEnv_*, _jobject*, _jclass*) + 0x69
- JvmtiExport::post_class_load(JavaThread*, Klass*) + 0x15b
- SystemDictionary::resolve_instance_class_or_null(Symbol*, Handle, Handle, Thread*) + 0x87c
- SystemDictionary::resolve_or_fail(Symbol*, Handle, Handle, bool, Thread*) + 0x33
- get_mirror_from_signature(methodHandle, SignatureStream*, Thread*) + 0xc6
- Reflection::get_parameter_types(methodHandle, int, oopDesc**, Thread*) + 0x18e
- Reflection::new_method(methodHandle, bool, bool, Thread*) + 0xfc
- get_class_declared_methods_helper(JNIEnv_*, _jclass*, unsigned char, bool, Klass*, Thread*) + 0x479
- JVM_GetClassDeclaredMethods + 0xcb
* java/lang/Class.getDeclaredMethods0 @ -1
* java/lang/Class.privateGetDeclaredMethods @ 37
* java/lang/Class.privateGetMethodRecursive @ 2
* java/lang/Class.getMethod0 @ 16
* java/lang/Class.getMethod @ 13
* sun/launcher/LauncherHelper.validateMainClass @ 12
* sun/launcher/LauncherHelper.checkAndLoadMain @ 214