r3mbol
r3mbol

Reputation: 261

Why can't I load persistence.xml from OSGi/RCP/EclipseLink application?

We're making an RCP application using EclipseLink that is deployed into OSGi bundle. When we run the application in eclipse it works perfectly, after deploying on linux it works well, but when we deploy it under windows, it crashes.

Exception occures in following code:

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 is from org.eclipse.persistence.jpa.osgi package, connectionProperties

After running this code we get an org.eclipse.persistence.exceptions.PersistenceUnitLoadingException that is caused by java.net.MalformedURLException. Lots of debugging later, I can tell that OSGi definately finds this persistence.xml (eariler we had persistence.xml located in wrong directory and we had different exception, saying that no bundle was available that defined that persistence unit), it can easily retreive it (tested by manually loading and reading it). It seems to me that PersistenceUnitProcessor can't load right archive in findPersistenceArchives method (it seems that it returns one Archive after finding META-INF/persistence.xml file, but this Archive is empty).

I found something similar under link http://www.eclipse.org/forums/index.php/mv/msg/218408/693584/#msg_693584 . Though it's not exactly the same, but it covers eclipse and eclipseLink, but it's not applicable in our project.

I believe debugging deeper into libraries is pointless and error must be either in product export configuration or some bug in our code.

Both systems (windows XP and ubuntu 11.04) use same eclipse 3.7 with identical packages added, both have java 1.6u26, EclipseLink 2.3.0

Any ideas?

EDIT:

Just to make sure it's not something else that we might have screwed up in our project (since it's quite big right now) I made clean new project following those steps:

While from under eclipse it run smoothly, running deployed package returned following:

    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)

Upvotes: 4

Views: 3648

Answers (2)

Jan Hoeve
Jan Hoeve

Reputation: 325

We also had this problem.

In a nutshell, the solution for us was to subclass the ArchiveFactoryImpl (which belongs to jpa), override the isJarInputStream method so it always returns false (change if you want to perform a more sophisticated check..)

Then register this subclass by a system property:

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

The normal ArchiveFactoryImpl#isJarInputStream seems to react different starting from eclipse 3.7 (can anyone confirm this??). In that method a little trick is performed to 'check' if the given url is actually a JarInputStream. It seems that eclipse 3.7 has a slightly different way of resolving the url which causes the isJarInputStream to return true.

Upvotes: 3

r3mbol
r3mbol

Reputation: 261

Answer to this problem was (same as with few similar problems I found on internet) migrating to Hibernate.

My opinion is that PersistenceProvider from EclipseLink doesn't work well with bundleresource protocol. Anyways, switching to Hibernate PersistenceProvider worked like a charm.

Might I add that this migration was fairly painless, the main problem we had was with re-attaching dettached entities with lazy-type joins (Actually this problem is still bugging us, right now we have implemented a little workaround, but will have to return to it).

Upvotes: 1

Related Questions