From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 19942 invoked by alias); 23 Mar 2004 00:44:56 -0000 Mailing-List: contact mauve-discuss-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: mauve-discuss-owner@sources.redhat.com Received: (qmail 19926 invoked from network); 23 Mar 2004 00:44:53 -0000 Received: from unknown (HELO power.connexus.net.au) (203.12.22.20) by sources.redhat.com with SMTP; 23 Mar 2004 00:44:53 -0000 Received: from dholmeslaptop (dholmes.dltech.com.au [203.222.72.2]) by power.connexus.net.au (8.12.4/8.11.6) with SMTP id i2N0fFAd043210; Tue, 23 Mar 2004 11:41:15 +1100 (EST) (envelope-from dholmes@dltech.com.au) XAntiVirus: This e-mail has been scanned for viruses via the Connexus Internet Service From: "David Holmes" To: "Robert Lougher" , , , Cc: , Subject: RE: ClassLoader.findLoadedClass (was: ServiceFactory) Date: Tue, 23 Mar 2004 00:44:00 -0000 Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit In-Reply-To: X-SW-Source: 2004-q1/txt/msg00024.txt.bz2 Robert Lougher wrote: > Interesting -- that's a documentation change between 1.3 and 1.4. Yes see: http://developer.java.sun.com/developer/bugParade/bugs/4474902.html and then: http://developer.java.sun.com/developer/bugParade/bugs/4778645.html The change to "initiating classloader" was very deliberately done. > However, as Sascha points out, 1.4's explicitly says it should return > classes _recorded by the virtual machine_ as initiated by the loader. > Strictly, this doesn't mean all classes initiated by the loader, just the > ones recorded by the VM. As I said, if loadClass is called implicitly by > the VM it's recorded as an initiating loader, but not if > loadClass is called explicitly by the programmer. Allow me to take a walk through the spec here :) Section 5.3.2 of the JVMS states that after invoking loadClass on a loader the JVM records that the loader is an initiating loader of that class. This implies that the loaded class cache is maintained by the VM not the loader. However, if you read the OOPSLA '98 paper by Sheng Liang and Gilda Bracha "Dynamic Class Loading in the Java Virtual Machine, (which is referred to by the JLS and JVMS) it states that ClassLoader.findLoadedClass is the method that performs that lookup in the loaded class cache. So this supports Robert's position that only classes loaded by the VM get registered in the loaded class cache in this way. However, we now need to look at what happens if loadClass is called programmatically. For loadClass to actually return a Class object it must either successfully use defineClass - which is a final method and therefore part of the VM - or it must successfully delegate to a parent loader. According to JVMS 5.3.5 the final step in a successful defineClass is that the JVM marks the class as having that loader as its defining loader AND having that loader as an initiating loader. Hence after a successful l.defineClass(n) we must have l.findLoadedClass(n) returning true. If delegation is used then 5.3 defines that the loader is an initiating loader of the class. However, there is no explicit rule in 5.3 that states when in the delegation process the "initiating" loader is marked as an initiating loader. Similarly there is no obvious rule that states that when A delegates to B which delegates to C etc that any of the intervening loaders are marked as initiating loaders, even though by definition they are. So I conclude that Robert is correct. Although in Sascha's example, the classloader in question was by definition an initiating loader, it had not been used in a way that required it to be marked by the VM as an initiating loader and hence findLoadedClass was not required to return true. Initially I thought this exposed a hole in the type system but then realized that it does not. For although a given class could hold two reference to objects of Class N where N was defined by two different classloaders (L1 and L2), those references could only be typed as Object. If the class tried to define a field of type N then it would force marking of the initiating loader in a way that prevents two different classes for N being returned. Fun exercise :) Cheers, David Holmes