我在karaf 2.2.10之上使用JDO和datanucleus mongodb 3.2.3和spring 3.0.7。
在一个新的OSGi包安装上,我能够在mongodb上保持不出问题,但是在重新安装包之后,在构建一个新的PersistenceManagerFactory时会出现以下错误:
ERROR: Bundle [my_bundle] [242] Unable to get module class path.
(java.lang.IllegalStateException: zip file closed) 其中ID (242)引用第一个分配给包的ID (换句话说,旧包的ID )。
上一个包的上下文似乎是正确关闭的,以及“旧的”JDO PersistenceManagerFactory。
我的本地持久性管理器工厂bean类(基于dn站点中提供的示例):
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 { // somewhere else
classLoader = this.getClass().getClassLoader();
}
return classLoader;
}
@Override
public void setBundleContext(BundleContext bundleContext) {
this.bundleContext = bundleContext;
}
}一些与持久性有关的摘录来自上下文:
<!-- persistence manager factory -->
<bean id="pmf" class="[my_package].OSGiLocalPersistenceManagerFactoryBean">
<property name="configLocation" value="classpath:datanucleus.properties" />
</bean>
<!-- persistence manager factory proxy -->
<bean id="persistenceManagerFactoryProxy"
class="org.springframework.orm.jdo.TransactionAwarePersistenceManagerFactoryProxy">
<property name="targetPersistenceManagerFactory" ref="pmf" />
</bean>
<!-- transactions -->
<bean id="transactionManager" class="org.springframework.orm.jdo.JdoTransactionManager">
<property name="persistenceManagerFactory" ref="persistenceManagerFactoryProxy" />
</bean>
<tx:annotation-driven />错误消息似乎指向了类加载问题,但是为什么它只在重新部署期间失败呢?
任何提示都将不胜感激!
发布于 2013-10-23 11:32:49
请确保您还刷新了依赖的包,因为这些包通常会粘在旧的卸载包上。它还在那里直到所有的引用都被清除。在Karaf shell中,只需要在没有ID的情况下进行刷新或简单刷新,这将导致整个容器重新布线:)
发布于 2017-08-22 17:46:48
对于那些不能简单刷新javax.jdo的人,请确保您在重新创建PersistenceManagerFactory时重新创建自定义ClassLoader。如果Datanucleus没有更改,ClassLoader不会尝试加载同一类两次。最后,您将有ClassCastExceptions说不能将Entity.class转换为Entity.class。
https://stackoverflow.com/questions/19524534
复制相似问题