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


Reply via email to