Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 364748

Summary: MalformedURLException when parsing persistence.xml in persistence bundle
Product: [RT] Gemini.JPA Reporter: Michael Keith <michael.keith>
Component: CoreAssignee: Michael Keith <michael.keith>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: juergen.kissner, krum.tsvetkov, l.kirchev, milesg78, nobody, thomas.gillet.2
Version: 1.0.0   
Target Milestone: 1.1.0 M1   
Hardware: PC   
OS: Windows XP   
Whiteboard:

Description Michael Keith CLA 2011-11-24 14:39:02 EST
User reported the following:

Hello,

I've been using Gemini JPA over the past month with much success. Everything works nicely when running my product through the eclipse IDE. Unfortunately, I've encountered a series of problems while running they deployed product (deployed using the Product Export Wizard). This current problem has me a little stumped.

I'm running in an OSGi environment (equinox). I have a persistence bundle which the persistence unit xml file and entity classes.
When I attempt to "createEntityManagerFactory", I get a chain of exceptions which indicates a null URL. Unfortunately, I can't tell which URL is null, or why it is null in the release build and not in the eclipse ide environment. Perhaps your familiarity with the internal flow can uickly shed some light on what I'm missing, or what I should look for -- or which additional information you might need.
Unfortunately, it looks like the exception that might be giving me the information I need is being interrupted by another minor exception.
I'll keep perusing the code on your SCM webviews in the meantime.

Thanks for your help, and the technology.
Thanks,

Darren.




Attempting getResources(META-INF/persistence.xml) on org.eclipse.gemini.jpa.classloader.BundleProxyClassLoader@c25480([OUR PERSISTENCE BUNDLE #90])
Found resources(META-INF/persistence.xml) from org.eclipse.gemini.jpa.classloader.BundleProxyClassLoader@c25480([OUR PERSISTENCE BUNDLE #90])
Attempting getResources(META-INF/persistence.xml) on org.eclipse.gemini.jpa.classloader.BundleProxyClassLoader@39a91f(org.eclipse.gemini.jpa)
Local Exception Stack:
Exception [EclipseLink-30005] (Eclipse Persistence Services - 2.3.0.v20110604-r9504): org.eclipse.persistence.exceptions.PersistenceUnitLoadingException
Exception Description: An exception was thrown while searching for persistence archives with ClassLoader: org.eclipse.gemini.jpa.classloader.CompositeClassLoader@18e3c98
Internal Exception: Exception [EclipseLink-30009] (Eclipse Persistence Services - 2.3.0.v20110604-r9504): org.eclipse.persistence.exceptions.PersistenceUnitLoadingException
Exception Description: An exception was thrown while trying to load persistence unit at url: bundleresource://90.fwk8238128
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://90.fwk8238128
Internal Exception: java.net.MalformedURLException
at org.eclipse.persistence.exceptions.PersistenceUnitLoadingException.exceptionSearchingForPersistenceResources(PersistenceUnitLoadingException.java:126)
at org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactory(PersistenceProvider.java:115)
at org.eclipse.gemini.jpa.provider.EclipseLinkOSGiProvider.createEntityManagerFactory(EclipseLinkOSGiProvider.java:278)
at org.eclipse.gemini.jpa.proxy.EMFServiceProxyHandler.createEMF(EMFServiceProxyHandler.java:128)
at org.eclipse.gemini.jpa.proxy.EMFBuilderServiceProxyHandler.createEMF(EMFBuilderServiceProxyHandler.java:107)
at org.eclipse.gemini.jpa.proxy.EMFServiceProxyHandler.syncGetEMFAndSetIfAbsent(EMFServiceProxyHandler.java:106)
at org.eclipse.gemini.jpa.proxy.EMFBuilderServiceProxyHandler.invoke(EMFBuilderServiceProxyHandler.java:96)
at $Proxy13.createEntityManagerFactory(Unknown Source)
at org.eclipse.persistence.javax.persistence.osgi.OSGiProviderResolver.lookupEMFBuilder(Unknown Source)
at org.eclipse.persistence.javax.persistence.osgi.OSGiProviderResolver.createEntityManagerFactory(Unknown Source)
at javax.persistence.Persistence.createEntityManagerFactory(Unknown Source)
at [OUR CODE]
Caused by: Exception [EclipseLink-30009] (Eclipse Persistence Services - 2.3.0.v20110604-r9504): org.eclipse.persistence.exceptions.PersistenceUnitLoadingException
Exception Description: An exception was thrown while trying to load persistence unit at url: bundleresource://90.fwk8238128
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://90.fwk8238128
Internal Exception: java.net.MalformedURLException
at org.eclipse.persistence.exceptions.PersistenceUnitLoadingException.exceptionLoadingFromUrl(PersistenceUnitLoadingException.java:99)
at org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.processPersistenceArchive(PersistenceUnitProcessor.java:538)
at org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.getPersistenceUnits(PersistenceUnitProcessor.java:444)
at org.eclipse.persistence.internal.jpa.deployment.JPAInitializer.findPersistenceUnitInfoInArchive(JPAInitializer.java:172)
at org.eclipse.persistence.internal.jpa.deployment.JPAInitializer.findPersistenceUnitInfoInArchives(JPAInitializer.java:154)
at org.eclipse.persistence.internal.jpa.deployment.JPAInitializer.findPersistenceUnitInfo(JPAInitializer.java:135)
at org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactory(PersistenceProvider.java:73)
... 56 more
Caused by: 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://90.fwk8238128
Internal Exception: java.net.MalformedURLException
at org.eclipse.persistence.exceptions.PersistenceUnitLoadingException.exceptionProcessingPersistenceXML(PersistenceUnitLoadingException.java:117)
at org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.processPersistenceXML(PersistenceUnitProcessor.java:579)
at org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.processPersistenceArchive(PersistenceUnitProcessor.java:536)
... 61 more
Caused by: java.net.MalformedURLException
at java.net.URL.<init>(URL.java:617)
at java.net.URL.<init>(URL.java:480)
at java.net.URL.<init>(URL.java:429)
at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(XMLEntityManager.java:626)
at com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.determineDocVersion(XMLVersionDetector.java:189)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:799)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:764)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:123)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1210)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:568)
at org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.processPersistenceXML(PersistenceUnitProcessor.java:577)
... 62 more
Caused by: java.lang.NullPointerException
at java.net.URL.<init>(URL.java:522)
... 72 more
Comment 1 Nobody - feel free to take it CLA 2011-11-24 15:55:45 EST
osgi> props
System properties:
 awt.toolkit = sun.awt.windows.WToolkit
 equinox.use.ds = true
 file.encoding = Cp1252
 file.encoding.pkg = sun.io
 file.separator = \
 java.awt.graphicsenv = sun.awt.Win32GraphicsEnvironment
 java.awt.printerjob = sun.awt.windows.WPrinterJob
 java.class.path = plugins\org.eclipse.equinox.launcher_1.2.0.v20110502.jar
 java.class.version = 51.0
 java.endorsed.dirs = C:\Program Files (x86)\Java\jdk1.7.0_01\jre\lib\endorsed
 java.ext.dirs = C:\Program Files (x86)\Java\jdk1.7.0_01\jre\lib\ext;C:\Windows\Sun\Java\lib\ext
 java.home = C:\Program Files (x86)\Java\jdk1.7.0_01\jre
 java.library.path = C:\Program Files (x86)\Java\jdk1.7.0_01\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\TortoiseSVN\bin;C:\Qt\4.7.0\bin;C:\Program Files (x86)\Subversion\bin;%ANT_HOME%bin;%MAVEN_HOME%bin;C:\Program Files (x86)\Java\jdk1.7.0_01\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\TortoiseSVN\bin;C:\Qt\4.7.0\bin;C:\Program Files (x86)\Subversion\bin;%ANT_HOME%bin;%MAVEN_HOME%bin;C:\ProgramFiles (x86)\Java\jdk1.7.0_01\bin;C:\dev_tools\ant/bin;C:\dev_tools\maven/bin;.
 java.runtime.name = Java(TM) SE Runtime Environment
 java.runtime.version = 1.7.0_01-b08
 java.specification.name = Java Platform API Specification
 java.specification.vendor = Oracle Corporation
 java.specification.version = 1.7
 java.vendor = Oracle Corporation
 java.vendor.url = http://java.oracle.com/
 java.vendor.url.bug = http://bugreport.sun.com/bugreport/
 java.version = 1.7.0_01
 java.vm.info = mixed mode, sharing
 java.vm.name = Java HotSpot(TM) Client VM
 java.vm.specification.name = Java Virtual Machine Specification
 java.vm.specification.vendor = Oracle Corporation
 java.vm.specification.version = 1.7
 java.vm.vendor = Oracle Corporation
 java.vm.version = 21.1-b02
 org.osgi.framework.executionenvironment = OSGi/Minimum-1.0,OSGi/Minimum-1.1,OSGi/Minimum-1.2,JRE-1.1,J2SE-1.2,J2SE-1.3,J2SE-1.4,J2SE-1.5,JavaSE-1.6,JavaSE-1.7
 org.osgi.framework.language = en
 org.osgi.framework.os.name = Windows7
 org.osgi.framework.os.version = 6.1.0
 org.osgi.framework.processor = x86
 org.osgi.framework.system.capabilities = osgi.ee; osgi.ee="OSGi/Minimum"; version:List<Version>="1.0, 1.1, 1.2",osgi.ee; osgi.ee="JavaSE"; version:List<Version>="1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7"
 org.osgi.framework.system.packages = javax.accessibility,javax.activation,javax.activity,javax.annotation,javax.annotation.processing,javax.crypto,javax.crypto.interfaces,javax.crypto.spec,javax.imageio,javax.imageio.event,javax.imageio.metadata,javax.imageio.plugins.bmp,javax.imageio.plugins.jpeg,javax.imageio.spi,javax.imageio.stream,javax.jws,javax.jws.soap,javax.lang.model,javax.lang.model.element,javax.lang.model.type,javax.lang.model.util,javax.management,javax.management.event,javax.management.loading,javax.management.modelmbean,javax.management.monitor,javax.management.namespace,javax.management.openmbean,javax.management.relation,javax.management.remote,javax.management.remote.rmi,javax.management.timer,javax.naming,javax.naming.directory,javax.naming.event,javax.naming.ldap,javax.naming.spi,javax.net,javax.net.ssl,javax.print,javax.print.attribute,javax.print.attribute.standard,javax.print.event,javax.rmi,javax.rmi.CORBA,javax.rmi.ssl,javax.script,javax.security.auth,javax.security.auth.callback,javax.security.auth.kerberos,javax.security.auth.login,javax.security.auth.spi,javax.security.auth.x500,javax.security.cert,javax.security.sasl,javax.sound.midi,javax.sound.midi.spi,javax.sound.sampled,javax.sound.sampled.spi,javax.sql,javax.sql.rowset,javax.sql.rowset.serial,javax.sql.rowset.spi,javax.swing,javax.swing.border,javax.swing.colorchooser,javax.swing.event,javax.swing.filechooser,javax.swing.plaf,javax.swing.plaf.basic,javax.swing.plaf.metal,javax.swing.plaf.multi,javax.swing.plaf.nimbus,javax.swing.plaf.synth,javax.swing.table,javax.swing.text,javax.swing.text.html,javax.swing.text.html.parser,javax.swing.text.rtf,javax.swing.tree,javax.swing.undo,javax.tools,javax.transaction,javax.transaction.xa,javax.xml,javax.xml.bind,javax.xml.bind.annotation,javax.xml.bind.annotation.adapters,javax.xml.bind.attachment,javax.xml.bind.helpers,javax.xml.bind.util,javax.xml.crypto,javax.xml.crypto.dom,javax.xml.crypto.dsig,javax.xml.crypto.dsig.dom,javax.xml.crypto.dsig.keyinfo,javax.xml.crypto.dsig.spec,javax.xml.datatype,javax.xml.namespace,javax.xml.parsers,javax.xml.soap,javax.xml.stream,javax.xml.stream.events,javax.xml.stream.util,javax.xml.transform,javax.xml.transform.dom,javax.xml.transform.sax,javax.xml.transform.stax,javax.xml.transform.stream,javax.xml.validation,javax.xml.ws,javax.xml.ws.handler,javax.xml.ws.handler.soap,javax.xml.ws.http,javax.xml.ws.soap,javax.xml.ws.spi,javax.xml.ws.spi.http,javax.xml.ws.wsaddressing,javax.xml.xpath,org.ietf.jgss,org.omg.CORBA,org.omg.CORBA_2_3,org.omg.CORBA_2_3.portable,org.omg.CORBA.DynAnyPackage,org.omg.CORBA.ORBPackage,org.omg.CORBA.portable,org.omg.CORBA.TypeCodePackage,org.omg.CosNaming,org.omg.CosNaming.NamingContextExtPackage,org.omg.CosNaming.NamingContextPackage,org.omg.Dynamic,org.omg.DynamicAny,org.omg.DynamicAny.DynAnyFactoryPackage,org.omg.DynamicAny.DynAnyPackage,org.omg.IOP,org.omg.IOP.CodecFactoryPackage,org.omg.IOP.CodecPackage,org.omg.Messaging,org.omg.PortableInterceptor,org.omg.PortableInterceptor.ORBInitInfoPackage,org.omg.PortableServer,org.omg.PortableServer.CurrentPackage,org.omg.PortableServer.POAManagerPackage,org.omg.PortableServer.POAPackage,org.omg.PortableServer.portable,org.omg.PortableServer.ServantLocatorPackage,org.omg.SendingContext,org.omg.stub.java.rmi,org.w3c.dom,org.w3c.dom.bootstrap,org.w3c.dom.css,org.w3c.dom.events,org.w3c.dom.html,org.w3c.dom.ls,org.w3c.dom.ranges,org.w3c.dom.stylesheets,org.w3c.dom.traversal,org.w3c.dom.views,org.w3c.dom.xpath,org.xml.sax,org.xml.sax.ext,org.xml.sax.helpers
 org.osgi.framework.uuid = 00b80746-dd16-0011-1a4d-f7e1c4ab5502
 org.osgi.framework.vendor = Eclipse
 org.osgi.framework.version = 1.6.0
 org.osgi.supports.framework.extension = true
 org.osgi.supports.framework.fragment = true
 org.osgi.supports.framework.requirebundle = true
 os.arch = x86
 os.name = Windows 7
 os.version = 6.1
 osgi.arch = x86
 osgi.bundles = [OUR BUNDLE WHICH AUTO MANAGES INSTALLATION, RESOLVING, AND STARTING OF BUNDLES IN ORDER ACCORDING TO DOCUMENTATION]@1:start
 osgi.bundles.defaultStartLevel = 4
 osgi.console = true
 osgi.framework = [app root]/plugins/org.eclipse.osgi_3.7.1.R37x_v20110808-1106.jar
 osgi.framework.shape = jar
 osgi.framework.version = 3.7.1.R37x_v20110808-1106
 osgi.nl = en_US
 osgi.os = win32
 osgi.ws = win32
 path.separator = ;
 sun.arch.data.model = 32
 sun.awt.enableExtraMouseButtons = true
 sun.boot.class.path = C:\Program Files (x86)\Java\jdk1.7.0_01\jre\lib\resources.jar;C:\Program Files (x86)\Java\jdk1.7.0_01\jre\lib\rt.jar;C:\Program Files (x86)\Java\jdk1.7.0_01\jre\lib\sunrsasign.jar;C:\Program Files (x86)\Java\jdk1.7.0_01\jre\lib\jsse.jar;C:\Program Files (x86)\Java\jdk1.7.0_01\jre\lib\jce.jar;C:\Program Files (x86)\Java\jdk1.7.0_01\jre\lib\charsets.jar;C:\Program Files (x86)\Java\jdk1.7.0_01\jre\classes
 sun.boot.library.path = C:\Program Files (x86)\Java\jdk1.7.0_01\jre\bin
 sun.cpu.endian = little
 sun.cpu.isalist = pentium_pro+mmx pentium_pro pentium+mmx pentium i486 i386 i86
 sun.desktop = windows
 sun.io.unicode.encoding = UnicodeLittle
 sun.java.command = plugins\org.eclipse.equinox.launcher_1.2.0.v20110502.jar
 sun.java.launcher = SUN_STANDARD
 sun.jnu.encoding = Cp1252
 sun.management.compiler = HotSpot Client Compiler
 sun.os.patch.level =
 user.country = US
 user.language = en
 user.script =
 user.timezone = America/New_York
 user.variant =
Comment 2 Nobody - feel free to take it CLA 2011-11-24 16:23:44 EST
In the eclipse project, the persistence.xml is stored in ./src/META-INF/persistence.xml

In the produced .jar file, it is 'moved' to ./META-INF/persistence.xml

Here are the contents of MANIFEST.MF

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: [name]
Bundle-SymbolicName: [sym name];singleton:=true
Bundle-Version: 1.0.0.qualifier
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Import-Package: javax.persistence;jpa="2.0";version="1.1.0",
 [our additional packages]
Meta-Persistence: src/META-INF/persistence.xml
Export-Package: [our exported packages]
Bundle-ClassPath: .
Comment 3 Nobody - feel free to take it CLA 2011-11-25 15:55:51 EST
Hello.

I attached a debugger to investigate what was going on prior to the MalformedURLException (which is really a wrapped NullPointerException), and have identified some points where additional error checking may help the project:

org.eclipse.persistence.internal.jpa.deployment.JarInputStreamURLArchive.getEntry(String) line: 83	

The 'entries' collection is empty, so a null InputStream is returned.

When this null InputStream arrives in:
org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.processPersistenceArchive(Archive, ClassLoader) line: 536	

It is used in a call: 
org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.processPersistenceXML(URL, InputStream, ClassLoader) line: 547	

And the world unravels when that function creates a new InputSource
InputSource inputSource = new InputSource([null]);

Shortly after, it is used for parsing...
com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(InputSource) line: 561	
The null becomes a problem a few levels within .parse resulting in the MalformedURL

Hopefully this information is helpful.



So next, I must investigate what the JarInputStreamURLArchive had no entries -- which may technically out of the domain of gemini. I will post back when I learn more.
Comment 4 Nobody - feel free to take it CLA 2011-11-25 17:35:49 EST
I was able to circumvent the problem by deploying my persistence bundles in directory format instead of the default jar format. It seems that some of the time, the underlying systems are unable to access the contents of the jar to read META-INF/persistence.xml, despite being able to access it at other times* (possibly through other means). 

How to make a eclipse plug-in deploy in folder / directory form:
Include this line in the bundle's MANIFEST.MF
---
Eclipse-BundleShape: dir
---

Courtesy of the resolution of this bug:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=157562

This circumvents my problem, and allows me to use gemini for persistence. I am happy.

If you require any more information, or clarifications feel free to ask.
Thanks all.

D.

* I can determine that the contents of the jar'd bundle can be read, because when the various GEMINI_DEBUG flags are on, I was able to see the contents of persistence.xml printed out. This could perhaps be the bundle being prompted to reading from itself. The problem occurs when one of the jpa bundles attempts to access resourced from my jar'd persistence bundles.
Comment 5 Lazar Kirchev CLA 2012-01-11 04:02:41 EST
While I investigated the problem with the MalformedUrlException I came across the following. 

Previously, the JarInputStreamURLArchive was not used at all: in ArchiveFactoryImpl.createArchive() there is a check if the archive is a jar:

} else if (isJarInputStream(rootUrl)){
    result = new JarInputStreamURLArchive(rootUrl, descriptorLocation);
} else {
    result = new URLArchive(rootUrl, descriptorLocation);
}

In isJarInputStream(...) a call to openStream() is made. This used to return null, isJarInputSteram() returned false and then URLArchive() used to get created. 
After a change in the org.eclipse.osgi.baseadaptor.bundlefile.DirZipBundleEntry.getInputStream() (see bug 349121), it started to return an empty ByteArrayInputStream(), instead of null. This stream is returned by the openStream() and so isJarInputStream(...) returns true and JarInputStreamURLArchive started to get created.

This does not help to clarify why the JarInputStreamURLArchive has no entries, but at least makes clear why the MalformedUrlException (actually the NullPointerException) started to appear.
Comment 6 Krum Tsvetkov CLA 2012-02-20 02:28:59 EST
Hi,

The method org.eclipse.persistence.internal.jpa.deployment.ArchiveFactoryImpl.isJarInputStream(URL) has been modified in EclipseLink 2.3.2 and the problem does not appear with Gemini JPA 1.0 + EclipseLink 2.3.2.

Shall we close this ticket?
Comment 7 Michael Keith CLA 2012-03-27 09:38:25 EDT
Closing because we think it is fixed. 
If problem reappears, please reopen.