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

We are creating an RCP application using EclipseLink, which is deployed with the OSGi bundle. When we run the application in eclipse, it works fine, after deployment on linux it works fine, but when we deploy it under windows, it crashes.

An exception occurs in the 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 a package org.eclipse.persistence.jpa.osgi, connectionProperties

After running this code, we will get org.eclipse.persistence.exceptions.PersistenceUnitLoadingException by java.net.MalformedURLException . A lot of debugging later, I can say that OSGi definitely finds this persistence.xml (I have persistence.xml that had persistence.xml that was in the wrong directory and we had another exception saying that no package was available, which determined this persistence block), it can easily retreive it (checked by manual loading and reading). It seems to me that PersistenceUnitProcessor cannot load the right archive in the findPersistenceArchives method (it seems that it returns one archive after finding the META-INF / persistence.xml file, but this Archive is empty).

I found something similar at http://www.eclipse.org/forums/index.php/mv/msg/218408/693584/#msg_693584 . Although this is not exactly the same, it covers eclipse and eclipseLink, but this is not applicable in our project.

I believe that debugging more deeply in libraries is pointless, and the error should be either in the product export configuration, or in some error in our code.

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

Any ideas?

EDIT:

Just to make sure that this is not something else that we may have tied into our project (since it is quite large now), I made a new new project after the following steps:

  • A new plug-in project was created with the Hello RCP template and configuration.
  • The META-INF / persistence.xml file was created in the src package with the following contents:

     <?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 class created.

  • added to manifest.mf file:

     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 
  • added the necessary dependencies in the product configuration, made DummyEntity a JPA entity

  • Activator.start activation code added:

     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 } 
  • exported to a good executable package.

While it is running smoothly due to eclipse, launching a deployed package returns as follows:

  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) 
+4
source share
2 answers

We also had this problem.

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

Then register this subclass using the system property:

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

Normal ArchiveFactoryImpl # isJarInputStream seems to respond to different options since eclipse 3.7 (can anyone confirm this?). This method does a little trick to "check" if the given url is actually a JarInputStream. Eclipse 3.7 seems to have a slightly different way of resolving the url, due to which isJarInputStream returns true.

+3
source

The answer to this problem was the same as with a few similar problems that I found on the Internet), migrate to Hibernate.

I believe that the EclipseLink PersistenceProvider does not work with the bundleresource protocol. In any case, switching to Hibernate PersistenceProvider worked like a charm.

May I add that this migration was pretty painless, the main problem we encountered was re-installing dettached entities with associations with a lazy type (in fact, this problem is still listening to us, right now we have implemented a small workaround but should return to it).

+1
source

All Articles