首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >jdo/OSGi:包更新后构建JDO PersistenceManagerFactory的错误

jdo/OSGi:包更新后构建JDO PersistenceManagerFactory的错误
EN

Stack Overflow用户
提问于 2013-10-22 17:27:57
回答 2查看 285关注 0票数 0

我在karaf 2.2.10之上使用JDO和datanucleus mongodb 3.2.3和spring 3.0.7。

在一个新的OSGi包安装上,我能够在mongodb上保持不出问题,但是在重新安装包之后,在构建一个新的PersistenceManagerFactory时会出现以下错误:

代码语言:javascript
复制
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站点中提供的示例):

代码语言:javascript
复制
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;
    }
}

一些与持久性有关的摘录来自上下文:

代码语言:javascript
复制
<!-- 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 />

错误消息似乎指向了类加载问题,但是为什么它只在重新部署期间失败呢?

任何提示都将不胜感激!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-10-23 11:32:49

请确保您还刷新了依赖的包,因为这些包通常会粘在旧的卸载包上。它还在那里直到所有的引用都被清除。在Karaf shell中,只需要在没有ID的情况下进行刷新或简单刷新,这将导致整个容器重新布线:)

票数 2
EN

Stack Overflow用户

发布于 2017-08-22 17:46:48

对于那些不能简单刷新javax.jdo的人,请确保您在重新创建PersistenceManagerFactory时重新创建自定义ClassLoader。如果Datanucleus没有更改,ClassLoader不会尝试加载同一类两次。最后,您将有ClassCastExceptions说不能将Entity.class转换为Entity.class

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19524534

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档