It's now nearly three days that I was searching a solution for what seems to be a standard use case, namely to deploy a JavaEE6 web archive with EJBs and JPA persistence on Glassfish 3.1.2.2. The web app runs without errors on Tomee 1.5.1, and as JavaEE6 is a standard it should be not very difficult to run it on Glassfish. That was a terrible error. It drove me crazy to get JPA to work. Endless readings of specifications, documentations and forum entries did not help. At last I found the solution and I want to share it with those who run into the same difficulties.
Here is my simple web app:
- persistence.xml in WEB-INF/classes/META-INF
- cibet-1.3.jar in WEB-INF/lib containing EJBs, entities, a servlet and the rest of the classes
- empty beans.xml and ejb-jar.xml in cibet-1.3.jar/META-INF
The persistence.xml looks like this. One JTA PU, one resource-local PU. From the resource-local, an EntityManagerFactory is created from Persistence class in a Servlets init() method on deployment:
<persistence-unit name="Cibet" transaction-type="JTA">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<jta-data-source>CibetDS</jta-data-source>
<jar-file>../lib/cibet-1.3.jar</jar-file>
<class>com.logitags.ejbwar.TEntity</class>
</persistence-unit>
<persistence-unit name="CibetLocal" transaction-type="RESOURCE_LOCAL">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<jar-file>../lib/cibet-1.3.jar</jar-file>
<class>com.logitags.ejbwar.TEntity</class>
<properties>
<property name="openjpa.ConnectionURL" value="jdbc:derby://localhost:1527/cibettest"/>
<property name="openjpa.ConnectionDriverName" value="org.apache.derby.jdbc.ClientDriver"/>
<property name="openjpa.ConnectionUserName" value="APP"/>
<property name="openjpa.ConnectionPassword" value="x"/>
</properties>
</persistence-unit>
This runs without problems on Tomee. On Glassfish I got FileNotFoundException for cibet-1.3.jar and the EJBs are not deployed by the container. I played for two days changing the entries in persistence.xml, always Exceptions like:
Exception Description: An exception was thrown while searching for persistence archives with ClassLoader: WebappClassLoader (delegate=true; repositories=WEB-INF/classes/)
[file:/C:/Java/glassfish3/glassfish/domains/cibet/applications/ejbwar/WEB-INF/classes/lib/cibet-1.3.jar]
I read in EclipseLink documentation: "You have to ensure that any JAR file listed in the jar-file element is on the classpath of the deployment unit. Do so by manually adding the JAR file to the manifest classpath of the deployment unit." I tried but no success! I got errors like this:
2013-01-08 12:33:18,351 WARN [admin-thread-pool-4848(7)] (TldScanner.java:scanJar:464) - PWC6351: In TLD scanning, the supplied resource file:/C:/Java/glassfish3/glassfish/domains/cibet/applications/cibet-1.3.jar does not exist
java.io.FileNotFoundException: C:\Java\glassfish3\glassfish\domains\cibet\applications\cibet-1.3.jar (Das System kann die angegebene Datei nicht finden)
Finally, I found the solution by chance. Adding cibet.jar on Class-path of MANIFEST is not necessary. The following persistence.xml works:
<persistence-unit name="Cibet" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/Cibet</jta-data-source>
<jar-file>lib/cibet-1.3.jar</jar-file>
<class>com.logitags.ejbwar.TEntity</class>
</persistence-unit>
<persistence-unit name="CibetLocal" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jar-file>../lib/cibet-1.3.jar</jar-file>
<class>com.logitags.ejbwar.TEntity</class>
<properties>
<property name="eclipselink.jdbc.url" value="jdbc:oracle:thin:@192.168.1.64:1521:xe"/>
<property name="eclipselink.jdbc.driver" value="oracle.jdbc.OracleDriver"/>
<property name="eclipselink.jdbc.user" value="cibet"/>
<property name="eclipselink.jdbc.password" value="cibet"/>
</properties>
</persistence-unit>
You see? For JTA PU, the jar-file entry must be lib/cibet-1.3.jar, for the resource-local PU it must be ../lib/cibet-1.3.jar.
The JPA2 specification says: "Such JAR files are specified relative to the directory or jar file that contains the root of the persistence unit."
It seems there are interpretations about what is the root in a web archive. So who is right who is wrong? Tomee/OpenJpa or Glassfish/EclipseLink?
In any case, the fact that in EclipseLink two PUs in the same persistence.xml have different roots seems very very strange to me.