[kaffe] Kaffe CVS: kaffe hkraemer

Dalibor Topic robilad at yahoo.com
Mon May 19 14:18:01 PDT 2003

Hallo Helmer,

--- Helmer Krämer <hkraemer at freenet.de> wrote:

> first of all, failure of these tests doesn't mean that
> I commited something that is not working or something,
> these tests fail because some not so common actions 
> (like loading an array with elements of type void)
> result in different error messages than before.

Very true, I didn't take a look at the output of the other failed tests beside
the ArrayForName one, so I assumed they would be connected in some way. Sorry,
my bad.

> The problem with some of these tests is that I don't
> know why they were working before :(
> In detail:
> - ClassGC:
> This test fails because a "duplicate name" error occurs,
> which means that a classloader tries to defineClass() a
> class it has already loaded and defined before (or at
> least tried to do so). 
> This test creates its own classloader and loads a class
> called "ClassGCTest" with that classloader. Afterwards,
> the test runs the garbage collector (while still referencing
> the classloader) and thereafter tries to load another class
> called "ClassGCTestLater" (via its own classloader). This
> class in turn depends on the class "ClassGCTest", which
> causes the vm to again load the "ClassGCTest" class via
> the test's classloader. Since the test's classloader then
> simply loads and defines the class again, the "duplicate name"
> error occurs.
> The only way how this test can succeed is that the "ClassGCTest"
> class gets gc'ed during the invocation of the garbage collector.
> This however cannot happen in this case: First of all, every
> classloader references the classes it has already loaded and
> defined through its loadedClasses hashtable. Since the classloader
> that loaded and defined the "ClassGCTest" class (and thus keeps
> a reference to it) is still referenced during the garbage collection,
> the classloader itself and thus the "ClassGCTest" class cannot be
> gc'ed, which in turn means that this test can't succeed.
> So I'm either missing something obvious or I don't have a clue
> why this test succeeded before.

If I understand that correctly, the main problem is that
* a ClassLoader stores all loaded Classes in a HashMap
* since a ClassLoader is stored in its own class loader's HashMap, it is always
strongly reachable.
* so it can never be unloaded.

I believe that's a problem built for WeakHashMaps ;) So I'll try to create a
patch that stores ClassLoaders separately in a WeakHashMap and see if that

> - ProcessClassTest:
> Again, a "duplicate name" error occurrs, but isn't expected
> by the test.
> In this test case, a class called "Second" is to be loaded,
> which depends on a class "DontExist", which cannot be loaded
> because its class file doesn't exist. This causes kaffe to
> throw a NoClassDefFoundError while trying to bring "Second"
> to LINKED. This exception in turn prevents the classloader
> that loads "Second" from inserting "Second" into its loadedClasses
> hashtable. On the other hand, kaffe itself has created a class
> pool entry for "Second" and has recorded that someone tried to
> load "Second". Later during the test, "Second" is to be loaded a
> second time. Since "Second" is not in the loadedClasses hashtable,
> the classloader thinks it hasn't loaded "Second" yet and so loads
> "Second" again and tries to define it afterwards. However, since
> there already is an existing class pool entry for "Second", this
> causes kaffe to throw a "duplicate name" error.
> So it seems that this failure is caused by the loadedClasses
> hashtable and the class entries not being in sync, which is
> why I wonder why it worked before and how we could fix it?

I'm puzzled as well. For what it's worth, here's the output of java 1.4 vs the
expected output:

bash-2.05a$ java ProcessClassTest
A Segv java.lang.NullPointerException
B First java.lang.ExceptionInInitializerError
C Second java.lang.NoClassDefFoundError: DontExist
D Third java.lang.NoClassDefFoundError: DontExist
E Segv java.lang.NullPointerException
F First java.lang.NoClassDefFoundError
G Second java.lang.NoClassDefFoundError: DontExist
H Third java.lang.NoClassDefFoundError

bash-2.05a$ cat ProcessClassTest.out
A Segv java.lang.NullPointerException
B First java.lang.ExceptionInInitializerError: [exception was
C Second java.lang.NoClassDefFoundError: DontExist
D Third java.lang.ExceptionInInitializerError: [exception was
java.lang.NoClassDefFoundError: DontExist]
E Segv java.lang.NullPointerException
F First java.lang.NoClassDefFoundError: First
G Second java.lang.NoClassDefFoundError: Second
H Third java.lang.NoClassDefFoundError: Third

it differs for C and G.

dalibor topic

Do you Yahoo!?
The New Yahoo! Search - Faster. Easier. Bingo.

More information about the kaffe mailing list