为什么我不能从OSGi / RCP / EclipseLink应用程序加载persistence.xml?

时间:2011-08-10 11:26:46

标签: osgi eclipselink rcp

我们正在使用部署在OSGi包中的EclipseLink创建RCP应用程序。当我们在eclipse中运行应用程序时,它运行得很完美,在Linux上部署之后运行良好,但是当我们在windows下部署它时,它会崩溃。

以下代码中出现异常:

Map<String, Object> connectionProperties = new HashMap<String, Object>();
connectionProperties.put(PersistenceUnitProperties.CLASSLOADER, 
        this.getClass().getClassLoader());
PersistenceProvider pp = new PersistenceProvider();
entityManagerFactory = pp.createEntityManagerFactory(
        "persistence_unit", connectionProperties);

PersistenceProvider来自org.eclipse.persistence.jpa.osgi包,connectionProperties

运行此代码后,我们会收到由org.eclipse.persistence.exceptions.PersistenceUnitLoadingException引起的java.net.MalformedURLException。稍后调试很多,我可以告诉我OSGi肯定找到了这个persistence.xml(我们将persistence.xml定位在错误的目录中,我们有不同的异常,说没有可用于定义持久性单元的bundle),它可以轻松地进行检索它(通过手动加载和读取测试)。在我看来,PersistenceUnitProcessor无法在findPersistenceArchives方法中加载正确的存档(它似乎在找到META-INF / persistence.xml文件后返回一个存档,但此存档为空)。

我在链接http://www.eclipse.org/forums/index.php/mv/msg/218408/693584/#msg_693584下找到了类似的内容。虽然它不完全相同,但它涵盖了eclipse和eclipseLink,但它并不适用于我们的项目。

我认为深入调试库是没有意义的,错误必须是产品导出配置或代码中的一些错误。

两个系统(Windows XP和ubuntu 11.04)都使用相同的eclipse 3.7,添加了相同的软件包,两者都有java 1.6u26,EclipseLink 2.3.0

有什么想法吗?

修改

只是为了确保它们不是我们可能在项目中搞砸的其他东西(因为它现在非常大)我按照这些步骤制作了干净的新项目:

  • 使用Hello RCP模板和产品配置创建了新的插件项目。
  • 在src包中创建了META-INF / persistence.xml文件,其中包含以下内容:

    <?xml version="1.0" encoding="UTF-8"?>
    <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
        <persistence-unit name="pu" transaction-type="RESOURCE_LOCAL">
        <class>DummyEntity</class>
        <properties>
            <property name="javax.persistence.jdbc.url"
                value= database-url />
            <property name="javax.persistence.jdbc.user" value= database-user />
            <property name="javax.persistence.jdbc.password" value= database-password />
            <property name="javax.persistence.jdbc.driver" value="oracle.jdbc.OracleDriver" />  
        </properties>
    </persistence-unit>
    </persistence>  
    
  • 创建类DummyEntity。

  • 已添加到manifest.mf文件中:

    Import-Package: javax.persistence;jpa="2.0";version="2.0.3",
     org.eclipse.persistence.config;version="2.3.0.v20110604-r9504",
     org.eclipse.persistence.jpa;version="2.3.0.v20110604-r9504",
     org.eclipse.persistence.jpa.osgi;version="2.3.0.v20110604-r9504"
    JPA-PersistenceUnits: pu
    
  • 在产品配置中添加了必需的依赖项,使DummyEntity成为JPA实体

  • 将代码添加到Activator.start:

    import javax.persistence.EntityManagerFactory;
    import org.eclipse.persistence.config.PersistenceUnitProperties;
    import org.eclipse.persistence.jpa.osgi.PersistenceProvider;
    
    ...
    
    Map<String, Object> connectionProperties = new HashMap<String, Object>();
    connectionProperties.put(PersistenceUnitProperties.CLASSLOADER, this
            .getClass().getClassLoader());
    
    try {
        EntityManagerFactory emf = new PersistenceProvider()
                .createEntityManagerFactory("pu", connectionProperties);
    
        log("Connection established");
    } catch (Exception e) {
                 // here some code to log the exception stack trace
    }
    
  • 导出到漂亮的可执行包中。

从eclipse下运行顺利,运行已部署的包后返回:

    EXCEPTION
    org.eclipse.persistence.exceptions.PersistenceUnitLoadingException : 
    Exception Description: An exception was thrown while trying to load persistence unit at url: bundleresource://34.fwk2279771
    Internal Exception: Exception [EclipseLink-30004] (Eclipse Persistence Services - 2.3.0.v20110604-r9504): org.eclipse.persistence.exceptions.PersistenceUnitLoadingException
    Exception Description: An exception was thrown while processing persistence.xml from URL: bundleresource://34.fwk2279771
    Internal Exception: java.net.MalformedURLException
    TRACE:
    org.eclipse.persistence.exceptions.PersistenceUnitLoadingException.exceptionLoadingFromUrl(PersistenceUnitLoadingException.java:99)
    org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.processPersistenceArchive(PersistenceUnitProcessor.java:538)
    org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.getPersistenceUnits(PersistenceUnitProcessor.java:444)
    org.eclipse.persistence.internal.jpa.deployment.JPAInitializer.initPersistenceUnits(JPAInitializer.java:282)
    org.eclipse.persistence.internal.jpa.deployment.JPAInitializer.initialize(JPAInitializer.java:265)
    org.eclipse.persistence.jpa.osgi.PersistenceProvider.getInitializer(PersistenceProvider.java:91)
    org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactory(PersistenceProvider.java:71)
    rcptest.Activator.start(Activator.java:66)
    org.eclipse.osgi.framework.internal.core.BundleContextImpl$1.run(BundleContextImpl.java:711)
    java.security.AccessController.doPrivileged(Native Method)
    org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:702)
    org.eclipse.osgi.framework.internal.core.BundleContextImpl.start(BundleContextImpl.java:683)
    org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(BundleHost.java:381)
    org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:299)
    org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:440)
    org.eclipse.osgi.internal.loader.BundleLoader.setLazyTrigger(BundleLoader.java:268)
    org.eclipse.core.runtime.internal.adaptor.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107)
    org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findLocalClass(ClasspathManager.java:462)
    org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.findLocalClass(DefaultClassLoader.java:216)
    org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:400)
    org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:476)
    org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:429)
    org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:417)
    org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)
    java.lang.ClassLoader.loadClass(Unknown Source)
    org.eclipse.osgi.internal.loader.BundleLoader.loadClass(BundleLoader.java:345)
    org.eclipse.osgi.framework.internal.core.BundleHost.loadClass(BundleHost.java:229)
    org.eclipse.osgi.framework.internal.core.AbstractBundle.loadClass(AbstractBundle.java:1207)
    org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174)
    org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905)
    org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243)
    org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55)
    org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:191)
    org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
    org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
    org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344)
    org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    java.lang.reflect.Method.invoke(Unknown Source)
    org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
    org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
    org.eclipse.equinox.launcher.Main.run(Main.java:1410)

    org.eclipse.persistence.exceptions.PersistenceUnitLoadingException : 
    Exception Description: An exception was thrown while processing persistence.xml from URL: bundleresource://34.fwk2279771
    Internal Exception: java.net.MalformedURLException
    TRACE:
    org.eclipse.persistence.exceptions.PersistenceUnitLoadingException.exceptionProcessingPersistenceXML(PersistenceUnitLoadingException.java:117)
    org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.processPersistenceXML(PersistenceUnitProcessor.java:579)
    org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.processPersistenceArchive(PersistenceUnitProcessor.java:536)
    org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.getPersistenceUnits(PersistenceUnitProcessor.java:444)
    org.eclipse.persistence.internal.jpa.deployment.JPAInitializer.initPersistenceUnits(JPAInitializer.java:282)
    org.eclipse.persistence.internal.jpa.deployment.JPAInitializer.initialize(JPAInitializer.java:265)
    org.eclipse.persistence.jpa.osgi.PersistenceProvider.getInitializer(PersistenceProvider.java:91)
    org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactory(PersistenceProvider.java:71)
    rcptest.Activator.start(Activator.java:66)
    org.eclipse.osgi.framework.internal.core.BundleContextImpl$1.run(BundleContextImpl.java:711)
    java.security.AccessController.doPrivileged(Native Method)
    org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:702)
    org.eclipse.osgi.framework.internal.core.BundleContextImpl.start(BundleContextImpl.java:683)
    org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(BundleHost.java:381)
    org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:299)
    org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:440)
    org.eclipse.osgi.internal.loader.BundleLoader.setLazyTrigger(BundleLoader.java:268)
    org.eclipse.core.runtime.internal.adaptor.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107)
    org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findLocalClass(ClasspathManager.java:462)
    org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.findLocalClass(DefaultClassLoader.java:216)
    org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:400)
    org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:476)
    org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:429)
    org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:417)
    org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)
    java.lang.ClassLoader.loadClass(Unknown Source)
    org.eclipse.osgi.internal.loader.BundleLoader.loadClass(BundleLoader.java:345)
    org.eclipse.osgi.framework.internal.core.BundleHost.loadClass(BundleHost.java:229)
    org.eclipse.osgi.framework.internal.core.AbstractBundle.loadClass(AbstractBundle.java:1207)
    org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174)
    org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905)
    org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243)
    org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55)
    org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:191)
    org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
    org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
    org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344)
    org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    java.lang.reflect.Method.invoke(Unknown Source)
    org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
    org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
    org.eclipse.equinox.launcher.Main.run(Main.java:1410)

    java.net.MalformedURLException : null
    TRACE:
    java.net.URL.<init>(Unknown Source)
    java.net.URL.<init>(Unknown Source)
    java.net.URL.<init>(Unknown Source)
    com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(Unknown Source)
    com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.determineDocVersion(Unknown Source)
    com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
    com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
    com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
    org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.processPersistenceXML(PersistenceUnitProcessor.java:577)
    org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.processPersistenceArchive(PersistenceUnitProcessor.java:536)
    org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.getPersistenceUnits(PersistenceUnitProcessor.java:444)
    org.eclipse.persistence.internal.jpa.deployment.JPAInitializer.initPersistenceUnits(JPAInitializer.java:282)
    org.eclipse.persistence.internal.jpa.deployment.JPAInitializer.initialize(JPAInitializer.java:265)
    org.eclipse.persistence.jpa.osgi.PersistenceProvider.getInitializer(PersistenceProvider.java:91)
    org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactory(PersistenceProvider.java:71)
    rcptest.Activator.start(Activator.java:66)
    org.eclipse.osgi.framework.internal.core.BundleContextImpl$1.run(BundleContextImpl.java:711)
    java.security.AccessController.doPrivileged(Native Method)
    org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:702)
    org.eclipse.osgi.framework.internal.core.BundleContextImpl.start(BundleContextImpl.java:683)
    org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(BundleHost.java:381)
    org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:299)
    org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:440)
    org.eclipse.osgi.internal.loader.BundleLoader.setLazyTrigger(BundleLoader.java:268)
    org.eclipse.core.runtime.internal.adaptor.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:107)
    org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findLocalClass(ClasspathManager.java:462)
    org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.findLocalClass(DefaultClassLoader.java:216)
    org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:400)
    org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:476)
    org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:429)
    org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:417)
    org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)
    java.lang.ClassLoader.loadClass(Unknown Source)
    org.eclipse.osgi.internal.loader.BundleLoader.loadClass(BundleLoader.java:345)
    org.eclipse.osgi.framework.internal.core.BundleHost.loadClass(BundleHost.java:229)
    org.eclipse.osgi.framework.internal.core.AbstractBundle.loadClass(AbstractBundle.java:1207)
    org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI.createExecutableExtension(RegistryStrategyOSGI.java:174)
    org.eclipse.core.internal.registry.ExtensionRegistry.createExecutableExtension(ExtensionRegistry.java:905)
    org.eclipse.core.internal.registry.ConfigurationElement.createExecutableExtension(ConfigurationElement.java:243)
    org.eclipse.core.internal.registry.ConfigurationElementHandle.createExecutableExtension(ConfigurationElementHandle.java:55)
    org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:191)
    org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
    org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
    org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344)
    org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    java.lang.reflect.Method.invoke(Unknown Source)
    org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
    org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
    org.eclipse.equinox.launcher.Main.run(Main.java:1410)

2 个答案:

答案 0 :(得分:3)

我们也有这个问题。

简而言之,我们的解决方案是继承ArchiveFactoryImpl(属于jpa),重写isJarInputStream方法,因此它总是返回false(如果你想执行更复杂的检查,则更改...)

然后通过系统属性注册此子类:

System.setProperty(SystemProperties.ARCHIVE_FACTORY, OurArchiveFactoryImpl.class.getName());

正常的ArchiveFactoryImpl#isJarInputStream似乎从eclipse 3.7开始做出不同的反应(任何人都可以确认这个吗?)。 在该方法中,执行一个小技巧来“检查”给定的URL是否实际上是JarInputStream。似乎eclipse 3.7有一种稍微不同的解析url的方式,导致isJarInputStream返回true。

答案 1 :(得分:1)

这个问题的答案(与我在互联网上发现的类似问题相同)迁移到Hibernate。

我的观点是EclipseLink的PersistenceProvider与bundleresource协议不兼容。无论如何,切换到Hibernate PersistenceProvider就像一个魅力。

我可以补充一点,这次迁移是相当轻松的,我们遇到的主要问题是re-attaching dettached entities with lazy-type joins(实际上这个问题仍然困扰着我们,现在我们已经实施了一些解决方法,但必须返回它)。