Hi,
It's 10pm in the UK, after a long day in work so I don't want to write
a long explanation as I'll probably get it wrong :) What I do want to
explain is why JamVM reports "null" when it shouldn't do...
You're correct in working out that it's the VM which records the
initiating loader. It does this when it resolves a reference to a
class from a class loaded by a class loader. For each class, JamVM
maintains a reference to the defining class loader for it (null for the
bootclasspath loader), and a list of class loaders which were used in a
resolution attempt (the initiating loaders - the defining loader is
implicitly part of this). As this is only done by the VM, direct calls
programmically to the class loader aren't recorded.
So, from your description below, JamVM will have recorded
TestClassLoader as an initiating loader of TestClass2 and String.
However, it returns "null" because of a bug in Classpath. In fact, if
you read the message that David Holmes responded to, you'll see I
mentioned it:
http://sources.redhat.com/ml/mauve-discuss/2004-q1/msg00022.html
The problem is that ClassLoader in Classpath maintains its own list (in
Java) of the classes that it has defined -- this is what is searches
when you call findLoadedClass. Of course, this won't contain any of
the classes that the VM has recorded the loader as being as initiating
loader for. This can probably be traced back to a change Sun made in
the documentation for findLoadedClass between Java 1.3 and 1.4.
Initially it just said returns the classes loaded by this loader, which
is pretty vague. In 1.4 they tightened it up and explicitly stated
recorded as an initiating loader by the VM. Classpath is arguaby OK in
1.3, but is definately wrong against 1.4.
I initially fixed it by providing my own implementation of ClassLoader
along with all the other VM classes that are needed to interface
Classpath to a particular VM. This version overrode the one in
Classpath, and made findLoadedClass a native method implemented by the
VM. However, I removed it in JamVM 1.2.3 because of incompatible
changes between ClassLoader in Classpath 0.12 (if I remember) and the
CVS development version. I couldn't make my version compatible with
both, and I decided it was more important to have JamVM work with the
snapshot (for "ordinary" users) and CVS, for the Classpath developers
themselves (who use JamVM).
I'll raise it as a bug, and have findLoadedClass moved into the "VM
layer". In the meantime, the native implementation is still there in
JamVM 1.2.4. If you're feeling particularly interested, you can edit
ClassLoader in your Classpath installation and change findLoadedClass
to be native. It'll then use JamVMs implementation.
Good luck!
Rob.
> Yes, that should be correct, but VMs handle this very different. I made
> the following test:
[quoted text clipped - 45 lines]
> initiating loader of class TestClass2. I think the only way to do so is
> to recognize and inspect the parent.loadClass() calls (in case of the
> gnu classpath api).
>
> Julian
Julian Bartram - 17 Feb 2005 01:23 GMT
Hello!
Thanks for your detailed explanation.
By the way, I made a mistake. Sun's VM handle it in the same way as Kaffe.