Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Get Spring JPA, Hibernate, and OSGi to Play Nice?

I am attempting to get a WAR file to run inside of a Karaf OSGi container. The application runs correctly in stand-alone Jetty 6.1.26, but when the application is run inside of Karaf, I get the following exception and the Karaf instance freezes:

WARN  org.hibernate.ejb.packaging.InputStreamZippedJarVisitor - Unable to find 
file (ignored): bundle://125.0:240/ java.lang.NullPointerException: in is null

Note that the application is not relying on Hibernate in a separate OSGi bundle; it includes the hibernate jars in WEB-INF/lib.

I have examined the information on this post: Equinox (OSGi) and JPA/Hibernate - Finding Entities. However, the application is using JPA, rather than using Hibernate directly. The application's configuration is much like the 2nd option found in this post: Difference between configuring data source in persistence.xml and in spring configuration files. As such, I don't have a handle on a Hibernate SessionFactory that allows me to set the annotatedClasses property.

Any ideas on how to get past the exception?

like image 420
Adam Avatar asked Mar 17 '11 00:03

Adam


1 Answers

I worked in parallel with the author and I'll post our solution here for anyone that runs into this in the future.

The exception is thrown because Hibernate tries to unzip it's jar to look for the persistence classes. As other posts mention, OSGi does not allow Hibernate to act like a classloader, so this fails. The solution was specifying all of the classes that it needed to load by hand and then telling it not to try to load anything else.

We used a persistence.xml file and an orm.xml file (we used default names so we didn't have to specify either in our applicationContext.xml).

Our persistence.xml file simply pointed to the orm.xml using the <mapping-file> tag. It also included the <exclude-unlisted-classes/> tag to keep hibernate from trying to load additional classes.

Our orm.xml file used <entity class="path.to.my.class" metadata-complete="false"/> to call out every entity class that we needed to load. The metadata-complete part tells hibernate to use the annotations found in the class to complete the configuration.

like image 106
Jon7 Avatar answered Nov 13 '22 03:11

Jon7