Issue Details (XML | Word | Printable)

Key: NUCCORE-1243
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Unassigned
Reporter: Scott Leschke
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
DataNucleus Core

OSGI classloading problem

Created: 07/Aug/14 04:48 PM   Updated: 25/Aug/14 07:33 PM   Resolved: 08/Aug/14 09:41 AM
Component/s: OSGi
Affects Version/s: 4.0.1
Fix Version/s: 4.0.2

Environment: OSGi

Datastore: Microsoft SQL Server
Severity: Proof of Concept


 Description  « Hide
The following stacktrace is seen in the Apache Karaf logs. Upon investigation, it would appear that the DN core bundle merely needs to add to proper package imports (optional imports of the various store package) to the MANIFEST for this to work as expected. Of course there may be other packages that need importing as well in the core and other bundles. In addition, if loading using the thread context class loader, that loader will need to be set to the CL of the appropriate bundle, probably API or CORE. Take a look at:
 http://njbartlett.name/2012/10/23/dreaded-thread-context-classloader.html
or
 http://stackoverflow.com/questions/2198928/better-handling-of-thread-context-classloader-in-osgi


2014-08-06 13:03:13,932 | WARN | rs?tqx=reqId%3A0 | Persistence | 159 - org.datanucleus - 4.0.1 | Error creating validator of type org.datanucleus.store.rdbms.RDBMSPropertyValidator
org.datanucleus.exceptions.ClassNotResolvedException: Class "org.datanucleus.store.rdbms.RDBMSPropertyValidator" was not found in the CLASSPATH. Please check your specification and your CLASSPATH.
at org.datanucleus.ClassLoaderResolverImpl.classForName(ClassLoaderResolverImpl.java:213)
at org.datanucleus.ClassLoaderResolverImpl.classForName(ClassLoaderResolverImpl.java:374)
at org.datanucleus.Configuration.validatePropertyValue(Configuration.java:575)
at org.datanucleus.Configuration.setProperty(Configuration.java:503)
at org.datanucleus.Configuration.setPersistenceProperties(Configuration.java:482)
at org.datanucleus.api.jdo.JDOPersistenceManagerFactory.<init>(JDOPersistenceManagerFactory.java:508)
at org.datanucleus.api.jdo.JDOPersistenceManagerFactory.createPersistenceManagerFactory(JDOPersistenceManagerFactory.java:311)
at org.datanucleus.api.jdo.JDOPersistenceManagerFactory.getPersistenceManagerFactory(JDOPersistenceManagerFactory.java:212)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)[:1.7.0_65]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)[:1.7.0_65]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)[:1.7.0_65]
at java.lang.reflect.Method.invoke(Method.java:606)[:1.7.0_65]
at javax.jdo.JDOHelper$16.run(JDOHelper.java:1970)
at java.security.AccessController.doPrivileged(Native Method)[:1.7.0_65]
at javax.jdo.JDOHelper.invoke(JDOHelper.java:1965)[157:javax.jdo:3.1.0.rc1]
at javax.jdo.JDOHelper.invokeGetPersistenceManagerFactoryOnImplementation(JDOHelper.java:1171)[157:javax.jdo:3.1.0.rc1]
at javax.jdo.JDOHelper.getPersistenceManagerFactory(JDOHelper.java:849)[157:javax.jdo:3.1.0.rc1]
at javax.jdo.JDOHelper.getPersistenceManagerFactory(JDOHelper.java:722)[157:javax.jdo:3.1.0.rc1]

Sort Order: Ascending order - Click to sort in descending order
Andy Jefferson added a comment - 07/Aug/14 05:32 PM
DN core should NEVER import DN store plugins, for the obvious reason that core knows nothing about it (and nobody else needs it to use with OSGi). What happens if some third party writes another store plugin ? they have to request core be updated to "know about" it?

Suggest you look deeper, like how things are loaded from OSGi.

Andy Jefferson added a comment - 08/Aug/14 09:41 AM
GitHub Master changed to create property validators using plugin mechanism, and if not found then via ClassLoaderResolver. Who knows what effect that has on your case ... no testcase defined. Assumed "fixed". Either way "core" will never have info about downstream plugins added to its MANIFEST

Scott Leschke added a comment - 25/Aug/14 07:22 PM
For what it's worth, I feel I should respond. Sorry for the delay but I've been out of the office for a bit.

I never meant to imply that third-party datastore plugins would be handled this way, just the plugins under the org.datanucleus.store hierarchy. In my mind, these are a fundamental part of DN and shouldn't require any effort by the client to make use of then other than to simply deploy them to the OSGi framework while I would expect third-party plugins to be accessible via the datanucleus.primaryClassLoader property since they should be accessible through the client bundle.

I don't pretend to be an expert, but I think I have a pretty good grasp on how OSGi loads classes, enough to know that if there is no dependency on a package or bundle specified in the MANIFEST.MF, a classloader must be provided to DN for it to find the class. This means that the client bundle must import the necessary org.datanucleus.store package and provide the bundle's classloader via Thread.currentThread.setContextClassLoader. While feasible, I don't see it as a good solution as the client bundle has no explicit dependency on the store bundles. I realize it's a similar situation to giving the classloader of the org.datanucleus.api.jdo bundle to the javax.jdo bundle but in that case DN is a third-party product.

The other option(s) that I'm aware of would be to add the necessary store bundles to the OSGi framework bootdelegation set and that's really not a good solution.

If there's a solution I've overlooked, I'm like to here about it.

Just my two cents.

Thanks and best regards, Scott

Andy Jefferson added a comment - 25/Aug/14 07:33 PM
Scott, why not check the nightly build and report back if it works for you? I don't use OSGi so leave such things to people more expert than me in that domain ;-)