[kaffe] CVS kaffe (hkraemer): fix for Kaffe_FindClass
Kaffe CVS
cvs-commits at kaffe.org
Sat Jun 4 14:03:26 PDT 2005
PatchSet 6608
Date: 2005/06/04 20:58:29
Author: hkraemer
Branch: HEAD
Tag: (none)
Log:
fix for Kaffe_FindClass
Members:
ChangeLog:1.4134->1.4135
kaffe/kaffevm/jni/jni.c:1.31->1.32
Index: kaffe/ChangeLog
diff -u kaffe/ChangeLog:1.4134 kaffe/ChangeLog:1.4135
--- kaffe/ChangeLog:1.4134 Thu Jun 2 17:35:47 2005
+++ kaffe/ChangeLog Sat Jun 4 20:58:29 2005
@@ -1,3 +1,8 @@
+2005-06-04 Helmer Kraemer <hkraemer at freenet.de>
+
+ * kaffe/kaffevm/jni/jni.c (Kaffe_FindClass): fixed so it works correctly
+ for native methods of system classes.
+
2005-06-02 Guilhem Lavaux <guilhem at kaffe.org>
* kaffe/kaffevm/jni/jni.c
Index: kaffe/kaffe/kaffevm/jni/jni.c
diff -u kaffe/kaffe/kaffevm/jni/jni.c:1.31 kaffe/kaffe/kaffevm/jni/jni.c:1.32
--- kaffe/kaffe/kaffevm/jni/jni.c:1.31 Thu Jun 2 17:35:51 2005
+++ kaffe/kaffe/kaffevm/jni/jni.c Sat Jun 4 20:58:33 2005
@@ -317,34 +317,56 @@
return (cls);
}
-/*
- * For this routine, we defer most of the work to Class.forName(),
- * which handles the task of figuring out the right ClassLoader to
- * use based on the calling method, which requires examining the
- * stack backtrace.
- */
-
static jclass
Kaffe_FindClass(JNIEnv UNUSED *env, const char* name)
{
stackTraceInfo *trace;
- jstring nameString;
Utf8Const* utf8;
- jvalue retval;
+ Hjava_lang_ClassLoader *loader;
+ Hjava_lang_Class *clazz;
+ errorInfo einfo;
int i;
+ char* pathname;
BEGIN_EXCEPTION_HANDLING(NULL);
- /* We accepts slashes, but Class.forName() does not */
- utf8 = checkPtr(utf8ConstNew(name, -1));
- nameString = utf8Const2JavaReplace(utf8, '/', '.');
- utf8ConstRelease(utf8);
- checkPtr(nameString);
+ /* convert name to the form used inside the vm */
+ pathname = checkPtr(KMALLOC(strlen (name) + 1));
+ classname2pathname (name, pathname);
+
+ /* create a new utf8 constant */
+ utf8 = utf8ConstNew(pathname, -1);
+
+ /* free the internal form of name */
+ KFREE(pathname);
+
+ /* bail out if we could not create the utf8 constant */
+ if (utf8 == NULL)
+ {
+ postOutOfMemory (&einfo);
+ throwError (&einfo);
+ }
+ /* Quote from the JNI documentation:
+ *
+ * "In the Java 2 Platform, FindClass locates the class loader associated with the current native method.
+ * If the native code belongs to a system class, no class loader will be involved. Otherwise, the proper
+ * class loader will be invoked to load and link the named class. When FindClass is called through the
+ * Invocation Interface, there is no current native method or its associated class loader. In that case,
+ * the result of ClassLoader.getBaseClassLoader is used."
+ *
+ * So we ...
+ */
+
+ /* ... get the stacktrace ... */
trace = (stackTraceInfo *)buildStackTrace (NULL);
if (trace == NULL)
- return NULL;
+ {
+ postOutOfMemory (&einfo);
+ goto error_out;
+ }
+ /* ... find the first java method on the stack ... */
for (i=0; trace[i].meth != ENDOFSTACK; i++)
{
if ((trace[i].meth != NULL) &&
@@ -352,27 +374,58 @@
break;
}
+ /* ... determine the loader to be used ... */
if (trace[i].meth == ENDOFSTACK) {
- /* if there are no java methods on the stack, we use the system class loader */
+ jvalue retval;
+
do_execute_java_class_method (&retval, "java/lang/ClassLoader",
NULL,
"getSystemClassLoader",
"()Ljava/lang/ClassLoader;");
- do_execute_java_class_method(&retval, "java.lang.Class", NULL,
- "forName", "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;",
- nameString, true, retval.l);
+ loader = (Hjava_lang_ClassLoader *)retval.l;
} else {
- /* otherwise, we use the first java method on the stack */
- do_execute_java_class_method(&retval, "java.lang.Class", NULL,
- "forName", "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;",
- nameString, true, trace[i].meth->class->loader);
+ loader = trace[i].meth->class->loader;
}
- ADD_REF(retval.l);
+ /* ... and finally call loadArray or loadClass.
+ *
+ * Why don't we delegate to Class.forName? Our implementation of
+ * VMClassLoader.loadClass denies access to classes in internal
+ * packages like kaffe.lang or gnu.classpath (for security reasons).
+ * However, when FindClass is invoked from the native method of a
+ * class defined by the bootstrap loader, that is not correct.
+ * Therefore, we call loadClass / loadArray directly, which corresponds
+ * to what getClass() does.
+ */
+ if (utf8->data[0] == '[')
+ {
+ clazz = loadArray (utf8, loader, &einfo);
+ }
+ else
+ {
+ clazz = loadClass (utf8, loader, &einfo);
+ }
+
+ if (clazz == NULL)
+ {
+ goto error_out;
+ }
+
+ if (processClass (clazz, CSTATE_COMPLETE, &einfo) == false)
+ {
+ goto error_out;
+ }
+
+ ADD_REF(clazz);
+ utf8ConstRelease(utf8);
END_EXCEPTION_HANDLING();
- return (retval.l);
+ return (clazz);
+
+error_out:
+ utf8ConstRelease(utf8);
+ throwError (&einfo);
}
static jclass
More information about the kaffe
mailing list