我只能提供有關獲取JDO/DataNucleus將到Karaf基礎上工作的一些基本提示。
正如本教程所指出的那樣,您需要擴展LocalPersistenceManagerFactoryBean
,實現以及接口。
這裏的關鍵是類加載:LocalPersistenceManagerFactoryBean
期望所有的類都被一個類加載器加載,而在OSGi運行時則不是這種情況。
爲了得到它的工作,你將需要:
- 在您的清單文件中明確導入
org.datanucleus.api.jdo
。
- 的
datanucleus.primaryClassLoader
屬性可以設置爲你傳遞給JDOHelper.getPersistenceManagerFactory
方法相同的類加載器。類加載器是org.datanucleus.api.jdo
包使用的類加載器(請參見下面的示例)
- 您需要將
datanucleus.plugin.pluginRegistryClassName
屬性設置爲org.datanucleus.plugin.OSGiPluginRegistry
。
- 停止時/卸載你的包,你必須刷新
javax.jdo
包,以避免當重新創建持久性管理器工廠(關於這個問題的檢查this question)
的樣本定製LocalPersistenceManagerFactoryBean錯誤:
public class OSGiLocalPersistenceManagerFactoryBean
extends LocalPersistenceManagerFactoryBean implements BundleContextAware {
public static final String JDO_BUNDLE_NAME = "org.datanucleus.api.jdo";
public static final String JDO_PMF_CLASS_NAME = "org.datanucleus.api.jdo.JDOPersistenceManagerFactory";
private BundleContext bundleContext;
@Override
protected PersistenceManagerFactory newPersistenceManagerFactory(String name) {
return JDOHelper.getPersistenceManagerFactory(name, getClassLoader());
}
@Override
protected PersistenceManagerFactory newPersistenceManagerFactory(Map props) {
ClassLoader classLoader = getClassLoader();
props.put("datanucleus.primaryClassLoader", classLoader);
if (FrameworkUtil.getBundle(this.getClass()) != null) { // running in OSGi
props.put("datanucleus.plugin.pluginRegistryClassName", "org.datanucleus.plugin.OSGiPluginRegistry");
}
PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory(props, classLoader);
return pmf;
}
private ClassLoader getClassLoader() {
ClassLoader classLoader = null;
Bundle thisBundle = FrameworkUtil.getBundle(this.getClass());
if (thisBundle != null) { // on OSGi runtime
Bundle[] bundles = bundleContext.getBundles();
for (Bundle bundle : bundles) {
if (JDO_BUNDLE_NAME.equals(bundle.getSymbolicName())) {
try {
classLoader = bundle.loadClass(JDO_PMF_CLASS_NAME).getClassLoader();
} catch (ClassNotFoundException e) {
// do something fancy here ...
}
break;
}
}
} else { // on Java runtime
classLoader = this.getClass().getClassLoader();
}
return classLoader;
}
@Override
public void setBundleContext(BundleContext bundleContext) {
this.bundleContext = bundleContext;
}
}
感謝。我會看看。 – binarek
另請注意,所有數據包必須在啓動捆綁包時啓動。如果不這樣,則會在OSGIPluginRegistry中給出錯誤(NullPointerException)。 –