persistence.xml <jar-file> not following JSR220 spec
Description
Attachments
Activity
Steve Ebersole January 12, 2016 at 9:21 PM
So the crux of my change is:
for exploded roots I instead build the
File
and call toURI().toURL() rather than trying to build the URL "by hand"for archived roots I manually build a URL by hand because there is no other option
The code is:
Please be sure to verify that this still works with WF. Everyone else, please make sure that this expanded coverage works still in your particular case.
Steve Ebersole January 12, 2016 at 9:02 PM
Both of these solutions ultimately boil down to new URL(environment.getRootUrl(),url.getPath());
. However, that only works when the root is an exploded archive, at least in my testing. If environment.getRootUrl()
resolves to a file, then what I see is creating the new, relative URL creates the URL relative to the directory containing the archive root. So, for example... let's say we have a root URL of "file://the/path/to/the.par" and that that par defines a <jar-file/>
entry referencing "META-INF/entities.jar". So that call effectively becomes new URL( "file://the/path/to/the.par", "META-INF/entities.jar" )
. In my testing, that ultimately becomes: "file://the/path/to/META-INF/entities.jar"
.
I had to add very specific handling for resolution relative to an archive using JAR protocol URL handling and its "!/" syntax
Steve Ebersole January 12, 2016 at 6:43 PM
wrote:
I just wanted to see if we all agree that the root of the persistence unit is not the META-INF folder but the folder that contains the META-INF.
Yes that is the intent of the spec. The report is saying Hibernate is not honoring that. Although given that we pass the JPA TCK, that either means this is a gap in the TCK or the report is inaccurate. I am writing a test to verify.
Steve Ebersole January 12, 2016 at 6:36 PM
I am trying to write a test to reproduce

Scott Marlow January 12, 2016 at 6:32 PM
MyMainClass.class
META-INF\
entities.jar
persistence.xmlThe entities.jar file contains a simple JPA entity `test.MyEntity` annotated with @Entity.
The persistence.xml contains `<jar-file>META-INF/entities.jar</jar-file>`
I don't agree with putting the entities.jar in the META-INF folder but I assume that is showing the described problem that the persistence unit root is not used to find the jar-file element.
The below text is from the above mentioned JPA 2.1 spec section:
8.2.1.6.3 Jar Files
One or more JAR files may be specified using the jar-file elements instead of, or in addition to the mapping files specified in the mapping-file elements. If specified, these JAR files will be searched for managed persistence classes, and any mapping metadata annotations found on them will be processed, or they will be mapped using the mapping annotation defaults defined by this specification.Such JAR files are specified relative to the directory or jar file that contains [89] the root of the persistence unit. [90][89] This semantics applies to persistence.xml files written to the persistence_2_0.xsd or later schema. Due to ambiguity in the Java
Persistence 1.0 specification, provider-specific interpretation of the relative references used by this element may apply to earlier
versions.
[90] Persistence providers are encouraged to support this syntax for use in Java SE environments.
I'm not sure if Hibernate is or is not currently finding the jar-file via persistence unit root, which is required for JPA 2.0 + greater.
JSR220 says <jar-file> is relative to the root of the persistence unit, which is the place containing the META-INF/persistence.xml
This is not the case. Instead, it looks for the jar relative to the JVM working directory. (see JarVisitorFactory.java)
So providing an absolute file path in <jar-file> works, but not a relative path because the root changes changes based on the situation and environment. E.g., the directory you run ant, when running tomcat, etc.