db-jdo-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Michael Bouschen <mbo.t...@spree.de>
Subject Re: class loader issue in java model - ri11 security manager tests failing
Date Mon, 24 Oct 2005 20:37:25 GMT
Hi Martin,

I have implemented the JavaModel changes as we discussed. Now the 
Class.forName is called in a doPrivileged block to avoid the 
SecurityException.
The other change is that I moved all the code that checks for the right 
class loader to the RuntimeJavaModel. A JavaType lookup by name first 
gets the class instance using the class loader bound to the model 
instance. Then it gets the class loader from the class instance and 
delegates to JavaModel bound to this class loader. This makes sure that 
a JavaModel handles only classes that are loaded by th class loader 
bound to the JavaModel. There is one exception: all JavaModel instances 
know about all the PredefinedType instances (JavaType instances for 
primitive types, Java wrapper class, java.util classes etc.).

Attached find two patches created from the trunk(!) directory:
- JDO1-JavaModel.patch: ri11 changes. I tested this running the ri11 
tests and tck11 in a jdk1.5 environment (I'm using the enhancer changes 
you send over).
- JDO2-JavaModel.patch: the corresponding changes for JDO2. This changes 
classes in core20, enhancer20, runtime20 and fostore20. I run the 
fostore20 tests with jdk 1.4.

Please let me know what you think.

Regards Michael

>
> Hi Michael,
>
> unfortunately, the fix for the class registration problem, as we
> discussed it and as it was checked in, causes most of the ri11
> security manager junit tests to fail (138 out of 149 tests).
>
> The symptom is an AccessControlException ("getClassLoader") within
> method Class.forName(), called from ReflectionJavaModel.java:130.
>
> The issue is exposed by an almost trivial change that we discussed
> (see below): When calling Class.forName() to initialize a class, we
> decided to use the class' classloader instead of the one stored in
> the JavaModel instance.  As you pointed out, we then must fetch the
> classloader in a doPrivileged block.  (This block succeeds, the
> exception is really raised within Class.forName()).
>
> Though the code assumes that the stored and the fetched classloader
> are always the same here, we discussed that if they're not, this
> would result in an internal error that is very hard to track down,
> since the consequences might show up later and elsewhere depending
> on the order in which classes are registered.  We considered to
> guard against this case with an assertion or an explicit check.
>
> It turns out the stored and the fetched classloader may differ for
> two reasons, I think.
>
> First, clazz.getClassLoader() returns null for a number of classes
> like Date and ArrayList.  Craig has pointed out that this is the
> specified behaviour for classes loaded by the bootstrap classloader.
>
> The javadoc on Class.forName() says that if the loader argument is
> null (and other conditions apply), the security manager is checked
> for permission ("getClassLoader") to access the bootstrap class
> loader.  This check fails.
>
> When using the stored classloader, which is always non-null, instead
> of the fetched one as argument to clazz.forName(), this method does
> not issue a "getClassLoader" request, and all tests security manager
> junit tests pass then.
>
> But I'm not sure this is the right solution either.  Essentially,
> we'd represent Date, ArrayList etc. a multiple times in the Java
> model - in each model instance per application classloader - while
> they're only represented once in the JVM, by the bootstrap loader.
>
> There might be another case to consider why the stored and the
> fetched classloader may differ:  An application that uses multiple
> classloaders forming a parent-child hierarchy, it may happen that
> a PC class is loaded by a child classloader while it's superclasses
> or the persistent field types are loaded by a parent classloader.
>
> In this case, we probably do not want to have the type universe be
> duplicated in each java model instance (i.e. per classloader), but
> rather represent a class in the java model only as many times as
> it's loaded in the VM, that is, per "owning" classloader.
>
> Now, I do not know if we're already doing this (class represented in
> java model only for "owning" classloader), but it seems to me that
> the implicit assumption in ReflectionJavaModel.getJavaType() that the
> stored and the fetched classloader are always the same does not hold.
>
> That's why I'm not sure that always using the stored classloader
> (instead of the fetched one) would be a general solution either.
>
> Any thoughts?
>
> Sorry for the long email.  If you'd rather like to discuss details
> over phone, I'd have some time on Thursday morning (until 9:30am) or
> on Friday during or after our JDO phone con.  Craig and I discussed
> this issue briefly today.
>
> Thx,
> Martin
>

-- 
Michael Bouschen		Tech@Spree Engineering GmbH
mailto:mbo.tech@spree.de	http://www.tech.spree.de/
Tel.:++49/30/235 520-33		Buelowstr. 66			
Fax.:++49/30/2175 2012		D-10783 Berlin			


Mime
View raw message