question on class loading behavior on array classes
pcj at roundroom.net
Thu Jan 7 23:24:08 PST 2010
On Jan 6, 2010, at 10:40 PM, ravenex wrote:
> According the the JVM spec, 2nd edition, 5.3.3 Creating Array Classes,
> both the bootstrap class loader and user-defined class loaders can
> load array classes, and the corresponding class loaders involved are
> recorded as initiating class loaders.
> But starting from JDK 6, Sun's JDK by default doesn't allow array
> syntax in ClassLoader.loadClass()/ClassLoader.findSystemClass(); array
> classes couldn't be created by calling defineClass() anyway,
> so this
> effectively bans user-defined class loaders to be initiating class
> loaders for array classes.
I don't understand that conclusion. Class.forName and resolution of symbolic references for array classes should have that effect (even though the user-defined initiating loader isn't invoked for the array class).
> Calling Class.forName(className,
> initialize, classLoader) won't record classLoader as an initiating
> class loader for an array class either.
What exactly leads you to believe that?
> I'm expecting a call to Class.forName() would mark the loader as an
> initiating one, for all classes (including array classes). That way I
> won't have to keep a cache of my own in my custom class loader to keep
> track of what's been loaded already. I read Bug 6500212
> (http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6500212) and know
> that I shouldn't call ClassLoader.loadClass() with array syntax, so I
> switched to Class.forName(). But then when my class loader is asked to
> load the same array class again,
I'm confused: if you're not invoking ClassLoader.loadClass with array syntax, how does your class loader get "asked to load the same array class again"? Class.forName should process the array syntax itself and only ask your class loader to load the element type (if it is a reference type).
> it calls findLoadedClass() and gets a
> null back.
Since JDK 6, ClassLoader.findLoadedClass always returns null when passed array syntax. That doesn't mean that the loader is not (effectively) recorded as an initiating loader of that array class, though.
> That's pretty bad because I don't won't to get down to
> SystemDictionary::resolve_array_class_or_null() every time I load an
> array class. That'll force me to use my own cache to record just about
> the same info as what the VM already has, plus the array classes
> loaded, which looks like a bad smell to me.
I'm not quite sure what that concern is, because Class.forName should begin with the same initiating-loader-based cache lookup that ClassLoader.findLoadedClass does, except that it understands array classes too. Implementation-wise, "getting down" to resolve_array_class_or_null gets you to the VM's relevant cache lookup.
More information about the core-libs-dev