question on class loading behavior on array classes

ravenex ravenex at qq.com
Thu Jan 7 03:40:17 UTC 2010


Hi all,

I asked the question on jdk6-dev list, and Joe Darcy said here's a
better place to ask, so here I go.

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. Calling Class.forName(className, 
initialize, classLoader) won't record classLoader as an initiating 
class loader for an array class either.

Is this an intended behavior?

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, it calls findLoadedClass() and gets a 
null back. 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.

And, is it possible for future JDK releases to include more "default
operations" in the reflection API? I mean, something like .NET's Binder
 (http://msdn.microsoft.com/en-us/library/system.reflection.binder.aspx
), or just increasing overloads of Class.getMethod()/getMethods() 
would be great. The project I'm working on requires lots of reflective 
calls, some of which only the receiver type, the target methods name, 
the number of arguments, and the exact type of each argument (not 
parameter) is known; overload resolution would have to be done at 
runtime, where I need to find a best matching overload to invoke. In 
.NET, a default Binder provided by the Base Class Library (fetched via 
System.Type.DefaultBinder property), and it'll do the overload 
resolution for users. I guess it might be more efficient to implement 
this kind of feature in the core library, and I wonder what you guys 
think. My scenario here is pretty much something like what Fredrik 
Ohrstrom's proposed version of MethodHandle's generic invocation 
support implements, and if that kind of binding feature exists in the 
VM already, exposing it in public API for general consumption should 
be easy, I suppose.

Greetings,
Raven


More information about the core-libs-dev mailing list