When a class was loaded with name in a dot form and if another time
classloader would be asked about the same class but in a slash form
then classloader will try to load the class again. We should convert
class names to slash names at classloader_load() entry to avoid
loading the same class twice.

This bug led to infinite loop of initialization of
"gnu/java/awt/peer/gtk/GtkComponentPeer" because it is referenced from
somewhere in its initialization code with a dot form name:
"gnu.java.awt.peer.gtk.GtkComponentPeer".

Signed-off-by: Tomek Grabiec <tgrab...@gmail.com>
---
 vm/classloader.c |   31 ++++++++++++++++++++++---------
 vm/jato.c        |    5 ++++-
 2 files changed, 26 insertions(+), 10 deletions(-)

diff --git a/vm/classloader.c b/vm/classloader.c
index b612c86..173dd78 100644
--- a/vm/classloader.c
+++ b/vm/classloader.c
@@ -188,6 +188,18 @@ static int lookup_class(const char *class_name)
        return -1;
 }
 
+static char *dots_to_slash(const char *name)
+{
+       char *result = strdup(name);
+
+       for (unsigned int i = 0, n = strlen(name); i < n; ++i) {
+               if (result[i] == '.')
+                       result[i] = '/';
+       }
+
+       return result;
+}
+
 static char *class_name_to_file_name(const char *class_name)
 {
        char *filename;
@@ -197,11 +209,6 @@ static char *class_name_to_file_name(const char 
*class_name)
                return NULL;
        }
 
-       for (unsigned int i = 0, n = strlen(class_name); i < n; ++i) {
-               if (filename[i] == '.')
-                       filename[i] = '/';
-       }
-
        return filename;
 }
 
@@ -450,6 +457,12 @@ struct vm_class *classloader_load(const char *class_name)
 
        trace_push(class_name);
 
+       char *slash_class_name = dots_to_slash(class_name);
+       if (!slash_class_name) {
+               trace_pop();
+               return NULL;
+       }
+
        pthread_mutex_lock(&classloader_mutex);
 
        /*
@@ -457,8 +470,7 @@ struct vm_class *classloader_load(const char *class_name)
         * while we're loading a class or waiting for a class to get
         * loaded the classes array might get relocated.
         */
-       class_index = lookup_class(class_name);
-
+       class_index = lookup_class(slash_class_name);
        if (class_index >= 0) {
                /* If class is being loaded by another thread then wait
                 * until loading is completed. */
@@ -492,7 +504,7 @@ struct vm_class *classloader_load(const char *class_name)
        class_index = nr_classes++;
 
        classes[class_index].loaded = false;
-       classes[class_index].class_name = class_name;
+       classes[class_index].class_name = slash_class_name;
 
        pthread_mutex_unlock(&classloader_mutex);
 
@@ -501,7 +513,7 @@ struct vm_class *classloader_load(const char *class_name)
         * load_class() because for example vm_class_init() might call
         * classloader_load() for superclasses.
         */
-       vmc = load_class(class_name);
+       vmc = load_class(slash_class_name);
        if (!vmc) {
                NOT_IMPLEMENTED;
                vmc = NULL;
@@ -521,6 +533,7 @@ struct vm_class *classloader_load(const char *class_name)
        pthread_mutex_unlock(&classloader_mutex);
 
  out:
+       free(slash_class_name);
        trace_pop();
        return vmc;
 }
diff --git a/vm/jato.c b/vm/jato.c
index e8f62fa..4a82048 100644
--- a/vm/jato.c
+++ b/vm/jato.c
@@ -440,7 +440,7 @@ native_vmclass_forname(struct vm_object *name, jboolean 
initialize,
                goto throw;
        }
 
-       const char *class_name = vm_string_to_cstr(name);
+       char *class_name = vm_string_to_cstr(name);
        if (!class_name) {
                NOT_IMPLEMENTED;
                return NULL;
@@ -448,6 +448,9 @@ native_vmclass_forname(struct vm_object *name, jboolean 
initialize,
 
        /* TODO: use @loader to load the class. */
        struct vm_class *class = classloader_load(class_name);
+
+       free(class_name);
+
        if (!class) {
                signal_new_exception(vm_java_lang_ClassNotFoundException,
                                     class_name);
-- 
1.6.0.6


------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with 
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Jatovm-devel mailing list
Jatovm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jatovm-devel

Reply via email to