Search code examples
javajvmjava-native-interface

When the Object.h / .cpp compiled


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)?

  • my question concerns the implementation of JVM
  • We assume that it was implemented in C / C ++

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.


Solution

  • 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);
        }
    }