| Summary: | DirectoryInsideJarURLArchive.getEntryAsURL returns incorrect URL for a valid war file persistence root | ||||||
|---|---|---|---|---|---|---|---|
| Product: | z_Archived | Reporter: | Albert Lee <allee8285> | ||||
| Component: | Eclipselink | Assignee: | Nobody - feel free to take it <nobody> | ||||
| Status: | CLOSED FIXED | QA Contact: | |||||
| Severity: | major | ||||||
| Priority: | P2 | CC: | allee8285, eclipselink.orm-inbox, tom.ware | ||||
| Version: | unspecified | ||||||
| Target Milestone: | --- | ||||||
| Hardware: | PC | ||||||
| OS: | Windows 7 | ||||||
| Whiteboard: | submitted_patch | ||||||
| Attachments: |
|
||||||
Any chance someone takes a look at the problem? Thanks. Setting target and priority. See the following page for the meanings of these fields: http://wiki.eclipse.org/EclipseLink/Development/Bugs/Guidelines Community: Please vote for this bug if it is important to you. Votes are one of the main criteria we use to determine which bugs to fix next. how does ArchiveBase.rootURL get set to: jar:file:/....../appl.war!/WEB-INF/classes/ We are likely expecting that to be something like jar:file:/../../../appl.war!/WEB-INF/classes/ What environment are you deploying in? What container? What OS? I am not correct about what we are expecting, but the questions above are still important. I am using EclipseLink 2.4.1 runs in the IBM WebSphere Liberty profile container in Windows 7. The test case is an web app with JPA artifacts in the war file's WEB-INF/classes/META-INF folder, which is one of the five supported location of the root of the persistence xml (8.2). Once I make the suggested changes, my test runs without further problem. Is it possible to provide the stack where you see the problem? (i.e. I want to know if this is in our initial jar exploration, if we are looking at a particular jar entry, or if we are looking up a file in the jar that is specified by <jar-file> or <mapping-file> I set a break point at DirectoryInsideJarURLArchive.getEntryAsURL and here is the call stack at the point of call: DirectoryInsideJarURLArchive.getEntryAsURL(String) line: 103 MetadataProcessor.loadStandardMappingFiles(String) line: 419 MetadataProcessor.loadMappingFiles(boolean) line: 344 PersistenceUnitProcessor.processORMetadata(MetadataProcessor, boolean, PersistenceUnitProcessor$Mode) line: 540 EntityManagerSetupImpl.predeploy(PersistenceUnitInfo, Map) line: 1469 PersistenceProvider.createContainerEntityManagerFactory(PersistenceUnitInfo, Map) line: 235 JPAPUnitInfo.createEMFactory(PersistenceUnitInfo) line: 1363 JPAPUnitInfo.createEntityManagerFactory() line: 1201 JPAPxmlInfo.extractPersistenceUnits(JPAPXml, ApplicationInfo) line: 236 JPAScopeInfo.processPersistenceUnit(JPAPXml, ApplicationInfo) line: 111 JPAApplInfo.addPersistenceUnits(JPAPXml) line: 132 JPAComponentImpl.processWebModulePersistenceXml(JPAApplInfo, WebModuleInfo) line: 770 JPAComponentImpl.moduleStarting(ModuleInfo) line: 624 If I let it free run, the server failed to start the application with the following stack: Internal Exception: java.lang.RuntimeException: java.net.MalformedURLException: no !/ in spec at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.createPredeployFailedPersistenceException(EntityManagerSetupImpl.java:1541) at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.predeploy(EntityManagerSetupImpl.java:1532) at org.eclipse.persistence.jpa.PersistenceProvider.createContainerEntityManagerFactory(PersistenceProvider.java:235) at com.ibm.ws.jpa.management.JPAPUnitInfo.createEMFactory(JPAPUnitInfo.java:1363) at com.ibm.ws.jpa.management.JPAPUnitInfo.createEntityManagerFactory(JPAPUnitInfo.java:1201) at com.ibm.ws.jpa.management.JPAPxmlInfo.extractPersistenceUnits(JPAPxmlInfo.java:236) at com.ibm.ws.jpa.management.JPAScopeInfo.processPersistenceUnit(JPAScopeInfo.java:111) at com.ibm.ws.jpa.management.JPAApplInfo.addPersistenceUnits(JPAApplInfo.java:132) at com.ibm.ws.jpa.management.JPAComponentImpl.processWebModulePersistenceXml(JPAComponentImpl.java:770) at com.ibm.ws.jpa.management.JPAComponentImpl.moduleStarting(JPAComponentImpl.java:624) Caused by: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.4.1.v20121003-ad44345): org.eclipse.persistence.exceptions.EntityManagerSetupException Exception Description: Predeployment of PersistenceUnit [jpasamplepersistenceunit] failed. Internal Exception: java.lang.RuntimeException: java.net.MalformedURLException: no !/ in spec at org.eclipse.persistence.exceptions.EntityManagerSetupException.predeployFailed(EntityManagerSetupException.java:221) ... 73 more Caused by: java.lang.RuntimeException: java.net.MalformedURLException: no !/ in spec at org.eclipse.persistence.internal.jpa.metadata.MetadataProcessor.loadStandardMappingFiles(MetadataProcessor.java:431) at org.eclipse.persistence.internal.jpa.metadata.MetadataProcessor.loadMappingFiles(MetadataProcessor.java:344) at org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.processORMetadata(PersistenceUnitProcessor.java:540) at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.predeploy(EntityManagerSetupImpl.java:1469) ... 71 more Caused by: java.net.MalformedURLException: no !/ in spec at java.net.URL.<init>(URL.java:613) at java.net.URL.<init>(URL.java:476) at java.net.URL.<init>(URL.java:425) at java.net.JarURLConnection.parseSpecs(JarURLConnection.java:172) at java.net.JarURLConnection.<init>(JarURLConnection.java:155) at sun.net.www.protocol.jar.JarURLConnection.<init>(JarURLConnection.java:78) at sun.net.www.protocol.jar.Handler.openConnection(Handler.java:36) at java.net.URL.openConnection(URL.java:957) at org.eclipse.persistence.internal.jpa.metadata.xml.XMLEntityMappingsReader.getInputStreamReader(XMLEntityMappingsReader.java:154) at org.eclipse.persistence.internal.jpa.metadata.xml.XMLEntityMappingsReader.read(XMLEntityMappingsReader.java:180) at org.eclipse.persistence.internal.jpa.metadata.MetadataProcessor.loadStandardMappingFiles(MetadataProcessor.java:425) ... 74 more Replace the additional suggested changes and the app server starts up with no problem. Can increase the loggging level to FINER or FINEST and post the log of deployment. (persistence unit property - eclipselink.logging.level=FINEST) I am looking a sequence of logs that contains this string just before the failure: "Searching for default mapping file in" BTW: You will likely be able to workaround this issue by not using a default orm.xml. i.e. you likely have a file called META-INF/orm.xml that is picked up by default. If you rename it to anything except orm.xml and list it as a <mapping-file> in your persistence.xml that will likely help you workaround the issue. [EL Finest]: 2013-08-19 13:40:24.155--ServerSession(832778659)--Thread(Thread[Scheduled Executor-thread-1,5,Scheduled Executor Thread Group])--property=eclipselink.logging.thread; value=false [EL Finest]: 2013-08-19 13:40:24.179--ServerSession(832778659)--property=eclipselink.logging.parameters; value=true [EL Finest]: 2013-08-19 13:40:24.183--ServerSession(832778659)--Begin predeploying Persistence Unit jpasamplepersistenceunit; session jar:file:/c:/Users/leealber/concord.eclipselink/build.image/wlp/usr/servers/com.ibm.ws.jpa.eclipselink.feature.fat.server/dropins/JPASample.war!/WEB-INF/classes/_jpasamplepersistenceunit; state Initial; factoryCount 0 [EL Finest]: 2013-08-19 13:40:24.187--ServerSession(832778659)--property=eclipselink.orm.throw.exceptions; default value=true [EL Finest]: 2013-08-19 13:40:24.189--ServerSession(832778659)--property=eclipselink.weaving.changetracking; default value=true [EL Finest]: 2013-08-19 13:40:24.19--ServerSession(832778659)--property=eclipselink.weaving.lazy; default value=true [EL Finest]: 2013-08-19 13:40:24.191--ServerSession(832778659)--property=eclipselink.weaving.eager; default value=false [EL Finest]: 2013-08-19 13:40:24.192--ServerSession(832778659)--property=eclipselink.weaving.fetchgroups; default value=true [EL Finest]: 2013-08-19 13:40:24.193--ServerSession(832778659)--property=eclipselink.weaving.internal; default value=true [EL Finest]: 2013-08-19 13:40:24.195--ServerSession(832778659)--property=eclipselink.multitenant.tenants-share-emf; default value=true [EL Finest]: 2013-08-19 13:40:24.197--ServerSession(832778659)--property=eclipselink.multitenant.tenants-share-cache; default value=false [EL Finer]: 2013-08-19 13:40:24.229--ServerSession(832778659)--Searching for default mapping file in jar:file:/c:/Users/leealber/concord.eclipselink/build.image/wlp/usr/servers/com.ibm.ws.jpa.eclipselink.feature.fat.server/dropins/JPASample.war!/WEB-INF/classes/ (There is no English translation for this message.) I think your suggested change can be simplified to something like this:
public URL getEntryAsURL(String entryPath) throws IOException {
rootURL = rootURL.toString().startsWith("jar:") ? rootURL : new URL("jar:"+rootURL);
URL result = entries.contains(entryPath) ?
new URL(rootURL + entryPath) : null; // NOI18N
return result;
}
Basically, the main bug here is that relativeRootPath will always already be part of the rootURL. We get it by creating a connection on that URL and asking for the entryName. There is no way that it won't already be on the rootURL.
I do not have a recreation. Does the code above work for you? Applied your recommended fix to my workspace and the tests passed successfully. Created attachment 234589 [details]
proposed fix - 2.5.1
The attached proposed fix does 2 things:
1. Avoid prepending "jar:" to a rootUrl that already starts with that
2. No longer adds relativeRootPath to the URL. If you look at the constructor for DirectoryInsideJarURLArchive, you can see that relativeRootPath is derived from the rootURL, but rootURL is never altered to remove it. Since we use rootURL directly, adding the relativeRootPath result in duplication as noted in the URL in the first comment in this bug.
Fix described above checked into 2.5.1 and main Reviewed by Chris Delahunt Tested by filer -> I do not have a license for the offending application server Ran JPA LRG tests The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink |
DirectoryInsideJarURLArchive.getEntryAsURL returns incorrect URL for a valid root of a persistence root. If ArchiveBase.rootURL is set to a valid root of a persistence unit in the form of: jar:file:/....../appl.war!/WEB-INF/classes/ getEntryAsURL(entryPath) returns jar:jar:file:/c:/....../appl.war!/WEB-INF/classes/!/WEB-INF/classes/${entryPath} It works after I change it to : public URL getEntryAsURL(String entryPath) throws IOException { String urlString = rootURL.toString(); urlString = urlString.startsWith("jar:") ? urlString : "jar:"+rootURL+"!/"+ relativeRootPath; URL result = entries.contains(entryPath) ? new URL( // "jar:"+rootURL+"!/"+ relativeRootPath urlString + entryPath) : null; // NOI18N return result; }