I have been trying to get my OSGI stuff to work with using JPA. As I am sure many here know, I need to create the EntityManagerFactory with Persistence.createEntityManagerFactory("my-factory"). Now, behind the scenes (am I supposed to read the sourcecode of the libraries as well? :)) this loads the persistence.xml from the META-INF directory on the classpath. With OSGI this always gives me the error "javax.persistence.PersistenceException: No Persistence provider for EntityManager named my-factory". After plenty of googling I came up with the reason that the persistence.xml is loaded using ThreadContext classloader, which in OSGI naturally fails. Reading up on it I also found only suggestions to use EclipseLink since it is "the only one build for OSGI and the JPA RI". Yet I get the same errors with it as well.
The only solution (after looong debugging sessions) I found that would work is the one given here:http://lsd.luminis.nl/jpa-persistence-in-osgi-with-openjpa/
. That is, to set the threadcontext classloader before call to createEntityManagerFactory and reset it after. I use Apache Felix as the OSGI container and I tried with both Hibernate JPA and EclipseLink JPA. Same problem every time, yet outside OSGI it all works perfectly (running the same code with JUnit). So, given that EclipseLink is the JPA RI and targets an OSGI environment, maybe someone can give me some answers here. My questions
- Why is there no option in Persistence.createEntityManagerFactory() to provide your own classloader to be used in loading of resources?
- Why is the only error message you can get for this the "javax.persistence.PersistenceException: No Persistence provider for EntityManager named my-factory"? No mention of "unable to find persistence.xml in classpath which is..." or "using classloaders..." or whatever. Just "unable to find" is a pretty bad message since it should know quite a bit more about why it is not able to find it (like missing persistence.xml for some reason).
Using the trick in the link above it all works fine. The only difference with "for OSGI" in EclipseLink vs Hibernate I see is that I need to import/export some stuff myself. Not much of an achievement considering how cryptic it is to get it working at all. Am I missing something?
To end more positively, thanks for all the efforts on JPA. Once I learn it, and when it works, it is nice enough :)