My question is: When is the Object.h/Object.cpp
(the java Class "Object"
) compiled?
Is it compiled along with JVM (when JVM is compiled) or it is included to the JVM dynamically (.dll)?
The philosophy of JNI is to create native methods and the communication between JVM and these classes are done via DLL files. But for native methods such a Object's native methods i cant understand if these methods communicate with the same way (via DLL files) or different.
It is not specified how JVM links Object's native methods; different JVM implementations may do it differently. As to OpenJDK and HotSpot JVM, there is no magic behind native methods of java.lang.Object
. They are bound the same way as user-defined natives.
Note: it is not required that the native code for a Java class is loaded from one shared library - it can be scattered round multiple libraries. That's exactly what happen to Object's native methods: some of them are built into JVM, others are implemented in java.dll
.
When java.lang.Object
class is initialized, its registerNatives
method is called. The native implementation of this method is a part of JDK class library. It is compiled from Object.c
into java.dll
at JDK build time.
static JNINativeMethod methods[] = {
{"hashCode", "()I", (void *)&JVM_IHashCode},
{"wait", "(J)V", (void *)&JVM_MonitorWait},
{"notify", "()V", (void *)&JVM_MonitorNotify},
{"notifyAll", "()V", (void *)&JVM_MonitorNotifyAll},
{"clone", "()Ljava/lang/Object;", (void *)&JVM_Clone},
};
JNIEXPORT void JNICALL
Java_java_lang_Object_registerNatives(JNIEnv *env, jclass cls)
{
(*env)->RegisterNatives(env, cls,
methods, sizeof(methods)/sizeof(methods[0]));
}
This method calls JNI RegisterNatives to bind other native methods of java.lang.Object
: hashCode
, wait
, notify
etc. The corresponding C++ functions JVM_IHashCode
, JVM_MonitorWait
and JVM_MonitorNotify
are a part of JVM. They are compiled from jvm.cpp
to jvm.dll
at HotSpot build time.
However, one more method, Object.getClass
is still implemented on JDK side using regular JNI interface:
JNIEXPORT jclass JNICALL
Java_java_lang_Object_getClass(JNIEnv *env, jobject this)
{
if (this == NULL) {
JNU_ThrowNullPointerException(env, NULL);
return 0;
} else {
return (*env)->GetObjectClass(env, this);
}
}