You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@openjpa.apache.org by Benjamin Renaud <be...@gmail.com> on 2008/11/01 00:23:07 UTC
createInstance calls Class.forName - unexpected behavior
Hi,
I've recently started developing an app using OpenJPA, and this is
what I am doing:
1. Let the user specify some arbitrary data (essentially classes with
fields)
2. Take that metadata and turn it into synthetic java interfaces, with
annotations.
3. Build a specific EMF that targets a specific Postgresql schema
4. Set my own ClassResolver on the EMF,
5. The ClassResolver returns a custom classloader which knows how to
make and load these synthetic interfaces, and runs calls the MetaData
facility on the class to create the OpenJPA MetaData.
6. Set the ContextClassLoader to my classloader. Get an EM from the
EMF, and call createInstance(syntheticClass) in the hope of coming up
with an entity I can persist and use.
This is where I am running into trouble.
I have determined that everything looks reasonable up until the point
where the OpenJPA runtime tried to instantiate the instance, in
org.apache.openjpa.meta.InterfaceImplGenerator.createImpl.
The following code snippet is where I hit a snag:
try {
meta.setInterfaceImpl(Class.forName(bc.getName(), true,
loader));
} catch (Throwable t) {
throw new InternalException(_loc.get("interface-load",
iface,
loader), t).setFatal(true);
}
(line 109 in my 1.2.0 source)
Debugging tells me that
- the SERP classloaders being used in this context (both the enhancer
and the regular loader, 'loader' in the snippet above) both have my
classloader as their parent (good).
- they also are both attached to a SERP project which -knows- about
the implementation class in question (in its names variable - which
therefore means that BCClassLoaders with it as their parent should be
able to load it), named something like my_package.my_interface
$myinterfaceopenjpaimpl
yet it basically can't find it.
It would appear that Class.forName in the snippet above ends up
calling findClass() in my classLoader but NOT findClass() in 'loader'
which ends up causing a ClassNotFoundException.
I can't explain why Class.forName doesn't do the right thing (it's
really a native method and the javadocs are a little vague), but I am
curious as to why the code snippet above doesn't simply call
loader.loadClass(bc.getName())?
Any insight into this issue would be much appreciated. (Including if I
am doing something unexpected)
Thank you,
Benjamin