classloader.c

来自「This is a resource based on j2me embedde」· C语言 代码 · 共 408 行

C
408
字号
/* * @(#)ClassLoader.c	1.79 06/10/10 * * Copyright  1990-2008 Sun Microsystems, Inc. All Rights Reserved.   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER   *    * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License version   * 2 only, as published by the Free Software Foundation.    *    * This program is distributed in the hope that it will be useful, but   * WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   * General Public License version 2 for more details (a copy is   * included at /legal/license.txt).    *    * You should have received a copy of the GNU General Public License   * version 2 along with this work; if not, write to the Free Software   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA   * 02110-1301 USA    *    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa   * Clara, CA 95054 or visit www.sun.com if you need additional   * information or have any questions.  * *//* %comment c017 */#include "jni.h"#include "jni_util.h"#include "jlong.h"#include "jvm.h"#include "java_lang_ClassLoader.h"#include "java_lang_ClassLoader_NativeLibrary.h"#include "jni_statics.h"#if 0  /* romized - not needed for CVM */static JNINativeMethod methods[] = {    {"retrieveDirectives",  "()Ljava/lang/AssertionStatusDirectives;", (void *)&JVM_AssertionStatusDirectives}};JNIEXPORT void JNICALLJava_java_lang_ClassLoader_registerNatives(JNIEnv *env, jclass cls){    (*env)->RegisterNatives(env, cls, methods, 			    sizeof(methods)/sizeof(JNINativeMethod));}#endif#include "javavm/include/globalroots.h"#include "javavm/include/indirectmem.h"#ifdef CVM_CLASSLOADING#include "generated/offsets/java_lang_ClassLoader.h"#endifJNIEXPORT void JNICALLJava_java_lang_ClassLoader_InitializeLoaderGlobalRoot(JNIEnv *env,						      jobject loader){#ifndef CVM_CLASSLOADING    return;#else    CVMExecEnv* ee = CVMjniEnv2ExecEnv(env);        /*      * Allocate a ClassLoader global root for the ClassLoader instance.     */    /*      * Access member variable of type 'int'     * and cast it to a native pointer. The java type 'int' only garanties      * 32 bit, but because one slot is used as storage space and     * a slot is 64 bit on 64 bit platforms, it is possible      * to store a native pointer without modification of     * java source code. This assumes that all places in the C-code     * are catched which set/get this member.     */    CVMAddr loaderGlobalRootInt;    CVMClassLoaderICell* loaderGlobalRoot = CVMID_getClassLoaderGlobalRoot(ee);    if (loaderGlobalRoot == NULL) {	CVMthrowOutOfMemoryError(ee, NULL);	return;    }    /* Make the global root point to the ClassLoader instance. */    CVMD_gcUnsafeExec(ee, {	CVMID_icellAssignDirect(ee, loaderGlobalRoot, loader);        /* This is the starting point from which the ClassLoader object           gets registered with the VM and special handling is required           to GC it later: */        CVMglobals.gcCommon.loaderCreatedSinceLastGC = CVM_TRUE;    });    /* Store a reference to the root in the ClassLoader object. */    loaderGlobalRootInt = (CVMAddr)loaderGlobalRoot;    CVMID_fieldWriteAddr(ee, loader,			 CVMoffsetOfjava_lang_ClassLoader_loaderGlobalRoot,			 loaderGlobalRootInt);    return;#endif}JNIEXPORT jclass JNICALLJava_java_lang_ClassLoader_defineClass0(JNIEnv *env,					jobject loader,					jstring name,					jbyteArray data,					jint offset,					jint length,					jobject pd){    jbyte *body;    char *utfName;    jclass result = 0;    char buf[128];    if (data == NULL) {	JNU_ThrowNullPointerException(env, 0);	return 0;    }    /* Work around 4153825. malloc crashes on Solaris when passed a     * negative size.     */    if (length < 0) {        JNU_ThrowArrayIndexOutOfBoundsException(env, 0);	return 0;    }    body = (jbyte *)malloc(length);    if (body == 0) {        JNU_ThrowOutOfMemoryError(env, 0);	return 0;    }    (*env)->GetByteArrayRegion(env, data, offset, length, body);    if ((*env)->ExceptionOccurred(env))        goto free_body;    if (name != NULL) {        int len = (*env)->GetStringUTFLength(env, name);	int unicode_len = (*env)->GetStringLength(env, name);        if (len >= sizeof(buf)) {            utfName = (char *)malloc(len + 1);            if (utfName == NULL) {                JNU_ThrowOutOfMemoryError(env, NULL);                goto free_body;            }        } else {            utfName = buf;        }    	(*env)->GetStringUTFRegion(env, name, 0, unicode_len, utfName);	VerifyFixClassname(utfName);    } else {	utfName = NULL;    }    result = JVM_DefineClass(env, utfName, loader, body, length, pd);    if (utfName && utfName != buf)         free(utfName); free_body:    free(body);    return result;}JNIEXPORT void JNICALLJava_java_lang_ClassLoader_resolveClass0(JNIEnv *env, jobject thisObj,					 jclass cls){    if (cls == NULL) {	JNU_ThrowNullPointerException(env, 0);	return;    }    JVM_ResolveClass(env, cls);}JNIEXPORT jclass JNICALLJava_java_lang_ClassLoader_loadBootstrapClass0(JNIEnv *env, jobject loader, 					       jstring classname){    char *clname;    jclass cls = NULL;    char buf[128];    int len;    int unicode_len;    CVMClassTypeID typeID = CVM_TYPEID_ERROR;    CVMClassBlock* cb;    CVMExecEnv* ee = CVMjniEnv2ExecEnv(env);    if (classname == NULL) {        JNU_ThrowClassNotFoundException(env, 0);	return NULL;    }    len = (*env)->GetStringUTFLength(env, classname);    unicode_len = (*env)->GetStringLength(env, classname);    if (len >= sizeof(buf)) {        clname = (char *)malloc(len + 1);        if (clname == NULL) {            JNU_ThrowOutOfMemoryError(env, NULL);            return NULL;        }    } else {        clname = buf;    }    (*env)->GetStringUTFRegion(env, classname, 0, unicode_len, clname);    VerifyFixClassname(clname);    if (!VerifyClassname(clname, JNI_TRUE)) {  /* expects slashed name */        JNU_ThrowClassNotFoundException(env, clname);	goto done;    }    /* get a typeid for the class name */    typeID = CVMtypeidNewClassID(ee, clname, len);    if (typeID == CVM_TYPEID_ERROR) {	goto done; /* exception already thrown */    }    /* See if it is a preloaded class or already in the loader cache */    cb = CVMclassLookupClassWithoutLoading(ee, typeID, NULL);    if (cb != NULL) {	cls = CVMcbJavaInstance(cb);	goto done;    }    /* load the class */    cls = CVMclassLoadBootClass(ee, clname);    if (cls == NULL) {	goto done;    }    /* We must free the global root returned, but not until after we've     * assigned it to another root to keep the Class alive until     * Class.loadSuperClasses() is called.     */    {	jclass tmp = CVMjniCreateLocalRef(ee);	if (tmp != NULL) {	    CVMID_icellAssign(ee, tmp, cls);	} else {	    /* exception already thrown. Class will be gc'd */	}	CVMID_freeGlobalRoot(ee, cls);	cls = tmp;    } done:    if (typeID != CVM_TYPEID_ERROR) {	CVMtypeidDisposeClassID(ee, typeID);    }    if (clname != buf) {    	free(clname);    }    return cls;}JNIEXPORT jclass JNICALLJava_java_lang_ClassLoader_findLoadedClass0(JNIEnv *env, jobject loader, 					   jstring name){    if (name == NULL) {	return 0;    } else {        return JVM_FindLoadedClass(env, loader, name);    }}JNIEXPORT jboolean JNICALL Java_java_lang_ClassLoader_00024NativeLibrary_initIDs(JNIEnv *env, jclass thisObj){    JNI_STATIC(java_lang_ClassLoader, handleID) = (*env)->GetFieldID(env, thisObj, "handle", "J");    if (JNI_STATIC(java_lang_ClassLoader, handleID) == 0)	return JNI_FALSE;    JNI_STATIC(java_lang_ClassLoader, jniVersionID) = (*env)->GetFieldID(env, thisObj, "jniVersion", "I");    if (JNI_STATIC(java_lang_ClassLoader, jniVersionID) == 0)	return JNI_FALSE;    JNI_STATIC(java_lang_ClassLoader, isXrunLibraryID) = (*env)->GetFieldID(env, thisObj, "isXrunLibrary", "Z");    if (JNI_STATIC(java_lang_ClassLoader, isXrunLibraryID) == 0)        return JNI_FALSE;    return JNI_TRUE;}typedef jint (JNICALL *JNI_OnLoad_t)(JavaVM *, void *);typedef void (JNICALL *JNI_OnUnload_t)(JavaVM *, void *);/* * Class:     java_lang_ClassLoader_NativeLibrary * Method:    load * Signature: (Ljava/lang/String;)J */JNIEXPORT void JNICALL Java_java_lang_ClassLoader_00024NativeLibrary_load  (JNIEnv *env, jobject thisObj, jstring name){    /* %comment kbr002 */    const char *cname;    jint jniVersion;    void * handle;    jboolean isXrunLibrary;    cname = JNU_GetStringPlatformChars(env, name, 0);    if (cname == 0)        return;    handle = JVM_LoadLibrary(cname);    isXrunLibrary =  (*env)->GetBooleanField(env, thisObj, JNI_STATIC(java_lang_ClassLoader, isXrunLibraryID));    if (handle && !isXrunLibrary) {        JNI_OnLoad_t JNI_OnLoad =	    (JNI_OnLoad_t)JVM_FindLibraryEntry(handle, "JNI_OnLoad");	if (JNI_OnLoad) {	    JavaVM *jvm;	    (*env)->GetJavaVM(env, &jvm);	    jniVersion = (*JNI_OnLoad)(jvm, NULL);	} else {	    jniVersion = JNI_VERSION_1_1;	} 	if ((*env)->ExceptionOccurred(env)) {	    JNU_ThrowByNameWithLastError(env, "java/lang/UnsatisfiedLinkError",					 "exception occurred in JNI_OnLoad");	    JVM_UnloadLibrary(handle);	    JNU_ReleaseStringPlatformChars(env, name, cname);	    return;	}   	if (!JVM_IsSupportedJNIVersion(jniVersion)) {	    char msg[256];	    jio_snprintf(msg, sizeof(msg),			 "unsupported JNI version 0x%08X required by %s",			 jniVersion, cname);	    JNU_ThrowByName(env, "java/lang/UnsatisfiedLinkError", msg);	    JVM_UnloadLibrary(handle);	    JNU_ReleaseStringPlatformChars(env, name, cname);	    return;	}	(*env)->SetIntField(env, thisObj, JNI_STATIC(java_lang_ClassLoader, jniVersionID), jniVersion);    }    (*env)->SetLongField(env, thisObj, JNI_STATIC(java_lang_ClassLoader, handleID), ptr_to_jlong(handle));    JNU_ReleaseStringPlatformChars(env, name, cname);}/* * Class:     java_lang_ClassLoader_NativeLibrary * Method:    unload * Signature: ()V */JNIEXPORT void JNICALL Java_java_lang_ClassLoader_00024NativeLibrary_unload  (JNIEnv *env, jobject thisObj){    void *handle;    jboolean isXrunLibrary;    handle = jlong_to_ptr((*env)->GetLongField(env, thisObj, JNI_STATIC(java_lang_ClassLoader, handleID)));    isXrunLibrary =  (*env)->GetBooleanField(env, thisObj, JNI_STATIC(java_lang_ClassLoader, isXrunLibraryID));    if (!isXrunLibrary) {        JNI_OnUnload_t JNI_OnUnload;        JNI_OnUnload = (JNI_OnUnload_t )            JVM_FindLibraryEntry(handle, "JNI_OnUnload");        if (JNI_OnUnload) {            JavaVM *jvm;            (*env)->GetJavaVM(env, &jvm);            (*JNI_OnUnload)(jvm, NULL);        }    }    JVM_UnloadLibrary(handle);}/* * Class:     java_lang_ClassLoader_NativeLibrary * Method:    find * Signature: (Ljava/lang/String;J)J */JNIEXPORT jlong JNICALL Java_java_lang_ClassLoader_00024NativeLibrary_find  (JNIEnv *env, jobject thisObj, jstring name){    jlong handle;    const char *cname;    jlong res;    handle = (*env)->GetLongField(env, thisObj, JNI_STATIC(java_lang_ClassLoader, handleID));    cname = (*env)->GetStringUTFChars(env, name, 0);    if (cname == 0)        return jlong_zero;    res = ptr_to_jlong(JVM_FindLibraryEntry(jlong_to_ptr(handle), cname));    (*env)->ReleaseStringUTFChars(env, name, cname);    return res;}JNIEXPORT jobject JNICALLJava_java_lang_ClassLoader_getCallerClassLoader(JNIEnv *env, jobject thisObj){    jclass caller = JVM_GetCallerClass(env, 2);    return caller != 0 ? JVM_GetClassLoader(env, caller) : 0;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?