Upgrade Hibernate version in JBOSS - java

I am having a hard time when trying to ship inside my EAR my own version of Hibernate (and not the one that JBoss brings by default).
Then I made my deployment "scoped" by including in the EAR a jboss-app.xml file containing the following:
<jboss-app>
<loader-repository>
com.example:archive=unique-archive-name
<loader-repository-config>
java2ParentDelegation=false
</loader-repository-config>
</loader-repository>
</jboss-app>
And, as usual, I declare my persistence provider in the persistence unit to be Hibernate, as follows:
<persistence>
<persistence-unit name="myapp">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
...
But then, the worst happens. On deployment, the server throws a ClassCastException when it tries to cast from org.hibernate.ejb.HibernatePersistence to the JPA interface javax.persistence.spi.PersistenceProvider (which IS implimented by HibernatePersistence).
This is kind of WEIRD, because I am shipping the JPA API also in my EAR, so, given that the classes of the EAR have priority to those of JBoss, it should have no problem when casting from HibernatePersistence to PersistenceProvider, since they "should be" on the same class loader.
If I don't ship my own JPA API, then the deployment fails with a ClassNotFoundException when JBoss tries to find some JPA class.
Any idea on why is this casting failing?
I am using JBoss 5.1.0, and trying to use Hibernate 3.5.6.Final. The JPA API version is the one imported transitively by the menctioned Hibernate version.

You could try turning on class scoping via the ear deployer. For JBoss 5.x edit:
jboss/server/[configuration]/deployers/ear-deployer-jboss-beans.xml
and change:
<bean name="EARClassLoaderDeployer" class="org.jboss.deployment.EarClassLoaderDeployer">
<property name="isolated">false</property>
</bean>
setting isolated to true.

Have you included the hibernate-entitymanager.jar too?
Otherwise you can try replacing the hibernate core jar in the common/lib with the 3.5.6 version.

To solve the class loading issues with hibernate in jboss server you need to add the jboss-classloading.xml inside the WEB-INF folder of your web application. Read more about these configuration settings here.
<classloading xmlns="urn:jboss:classloading:1.0"
domain="pentaho.ear"
export-all="NON_EMPTY"
import-all="true"
parent-first="false">
</classloading>

Related

Weblogic JPA 2.1 Hibernate 4 Not Working java.lang.NoSuchMethodError

I've run into the classic issue of trying to run a web app on a weblogic server and running into errors because of the weblogic server having old copies of classes.
The main issue I run into is when trying to use JPA 2.1 I get the following issue:
weblogic.application.ModuleException: java.lang.NoSuchMethodError: javax.persistence.Table.indexes()[Ljavax/persistence/Index;
The obvious answer here is that it is using the JPA version on the server which does not have that class.
I've set my weblogic.xml file to the following:
<wls:weblogic-web-app xmlns:wls="http://xmlns.oracle.com/weblogic/weblogic-web-app" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd http://xmlns.oracle.com/weblogic/weblogic-web-app http://xmlns.oracle.com/weblogic/weblogic-web-app/1.7/weblogic-web-app.xsd">
<wls:weblogic-version>12.1.3</wls:weblogic-version>
<wls:jsp-descriptor/>
<wls:debug>true</wls:debug>
</wls:jsp-descriptor>
<wls:container-descriptor>
<wls:prefer-web-inf-classes>true</wls:prefer-web-inf-classes>
</wls:container-descriptor>
<wls:context-root>DiscoveryPortal</wls:context-root>
</wls:weblogic-web-app>
With the key line being:
prefer-web-inf-classes: true
This seems to work for some classes but not all.
Weblogic 12c (supposedly) allows class filtering in both .war and .ear files. I would recommend moving from:
<wls:container-descriptor>
<wls:prefer-web-inf-classes>true</wls:prefer-web-inf-classes>
</wls:container-descriptor>
to:
<prefer-application-packages>
<package-name>javax.persistence.*</package-name>
</prefer-application-packages>
<prefer-application-resources>
<resource-name>javax.persistence.*</resource-name>
<resource-name>META-INF/services/javax.servlet.ServletContainerInitializer</resource-name>
</prefer-application-resources>
The filtering seems to work much better than prefer-web-inf-classes.
See the Oracle docs here that says it works for .war files. If not, you may consider switching to an .ear to see what happens.
Placing following code into weblogic.xml
<container-descriptor>
<prefer-application-packages>
<package-name>javax.persistence.*</package-name>
</prefer-application-packages>
</container-descriptor>
seems to be enough for related expection, on WebLogic Server 12.1.2.0 if you have JPA 2.1 jar on your classpath.
Official answer: "While WebLogic Server 12.1.3 supports JPA 2.1, the Java Archive (JAR) files are not configured by default; some additional configuration is required to enable JPA 2.1 support. In this tutorial, the JPA 2.1 implementation is configured on the WebLogic Server classpath."
And solution for weblogic is here: http://www.oracle.com/webfolder/technetwork/tutorials/obe/fmw/wls/12c/01-06-004-JavaEE7andWebLogicServer/javaee7.html
you need to add:
PRE_CLASSPATH=/YOUR_MIDDLEWARE_HOME/oracle_common/modules/javax.persistence_2.1.jar:/YOUR_MIDDLEWARE_HOME/wlserver/modules/com.oracle.weblogic.jpa21support_1.0.0.0_2-1.jar
export PRE_CLASSPATH
to setDomainEnv.sh which is located in your domain folder under 'bin' directory.
so you have inconsistent JPA API jar and Hibernate jars in the CLASSPATH.
JPA API 2.1 brought in that method and Hibernate 4.3 would be required to support that IIRC
I confirm that <wls:prefer-web-inf-classes>true</wls:prefer-web-inf-classes> doesn't work with WebLogic12/Spring4/Hibernate4/HibernateValidator5/JPA2.1,
you have to resort to <prefer-application-packages> but listing only java.persistence.* is far to be enough...
You have also to list:
javassist.*
org.hibernate.*
org.hibernate.validator.*
javax.validation.*
+
any other ones the Class Loader Analysis Tool will recommend you to include
+
include a ServletContextListener filter in your web.xml to register an "HibernatePersistencerProviderResolver implements PersistenceProviderResolver" that will return an singleton Collection holding an HibernatePersistenceProvider when called "getPersistenceProviders()"
if you are using Spring
in your Spring applicationContext to support method validation:
you need a bean "validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"
and another one
class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"
for your entityManager (class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean") jpaProperties:
<prop key="java.persistence.transactionType">jta</prop>
<prop key="hibernate.transaction.jta.platform">org.hibernate.engine.transaction.jta.platform.internal.WebLogicJtaPlatform</prop>
<prop key="hibernate.event.merge.entity_copy_observer">allow</prop>
if you are using maven, in your pom.xml (if using another build system refer to its doc to do the equivalent set-up)
you have to exclude org.jboss.spec.javax.transaction:jboss-transaction-api_1.1_spec from the dependencies org.hibernate:(hibernate-core and hibernate-entitymanager)
and then add it org.jboss.spec.javax.transaction:jboss-transaction-api_1.1_spec but as a "provided" independent dependency.
and last but not least…
DON'T use a persistence.xml !
not only with a LocalContainerEntityManagerFactoryBean you don't need it anymore but it will mess-up with WebLogic too and if you need to generate a DDL you can't use hbm2ddl anymore since the hibernate maven plugin is no more compatible with JPA2.1, you have to use an EntityManagerFactoryBuilder.generateSchema()... (not Persistence.generateSchema(...) as you will find when googling: this doesn't work without a persistence.xml...)

Is it possible to get rid of that extra #Resource annotation for Websphere-managed DataSource?

I have EJB application that is using OpenJPA persistence unit from WebSphere 8.5. The DataSource is configured on the WebSphere with the following settings:
Scope: cells:pxxxxNodexxCell
Name: MYAPP_001
JNDI name: jdbc/MYAPP/DS001
Component-managed authentication alias: MYAPP_001
Mapping-configuration alias: (none)
Container-managed authentication alias: (none)
The persistence unit is configured so:
<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="myapp" transaction-type="JTA">
<jta-data-source>java:comp/env/jdbc/MYAPP/DS001</jta-data-source>
<class>...</class>
<properties>
...
</properties>
</persistence-unit>
</persistence>
Now I'm importing it into EJB:
#PersistenceContext(name = "myapp")
private EntityManager em;
The problem is, that with the following configuration the data source can not be resolved:
Caused by:
org.apache.openjpa.persistence.ArgumentException: The persistence
provider is attempting to use properties in the persistence.xml file
to resolve the data source. A Java Database Connectivity (JDBC) driver
or data source class name must be specified in the
openjpa.ConnectionDriverName or javax.persistence.jdbc.driver
property. The following properties are available in the configuration:
"WsJpaJDBCConfigurationImpl#83f2eb8d: PDQ disabled: AccessIntent
Task=disable". at
org.apache.openjpa.jdbc.schema.DataSourceFactory.newDataSource(DataSourceFactory.java:72)
at
org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl.createConnectionFactory(JDBCConfigurationImpl.java:849)
at
org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl.getDBDictionaryInstance(JDBCConfigurationImpl.java:602)
at
org.apache.openjpa.jdbc.meta.MappingRepository.endConfiguration(MappingRepository.java:1518)
at
org.apache.openjpa.lib.conf.Configurations.configureInstance(Configurations.java:531)
at
org.apache.openjpa.lib.conf.Configurations.configureInstance(Configurations.java:456)
at
org.apache.openjpa.lib.conf.PluginValue.instantiate(PluginValue.java:121)
at
org.apache.openjpa.conf.MetaDataRepositoryValue.instantiate(MetaDataRepositoryValue.java:68)
at
org.apache.openjpa.lib.conf.ObjectValue.instantiate(ObjectValue.java:83)
at
org.apache.openjpa.conf.OpenJPAConfigurationImpl.newMetaDataRepositoryInstance(OpenJPAConfigurationImpl.java:967)
at
org.apache.openjpa.conf.OpenJPAConfigurationImpl.getMetaDataRepositoryInstance(OpenJPAConfigurationImpl.java:958)
at
org.apache.openjpa.kernel.AbstractBrokerFactory.makeReadOnly(AbstractBrokerFactory.java:644)
at
org.apache.openjpa.kernel.AbstractBrokerFactory.newBroker(AbstractBrokerFactory.java:203)
at
org.apache.openjpa.kernel.DelegatingBrokerFactory.newBroker(DelegatingBrokerFactory.java:156)
at
org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:227)
at
com.ibm.ws.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:72)
at
com.ibm.ws.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:35)
at
com.ibm.ws.jpa.management.JPAEMPool.getEntityManager(JPAEMPool.java:167)
at
com.ibm.ws.jpa.management.JPATxEntityManager.getEMInvocationInfo(JPATxEntityManager.java:247)
at
com.ibm.ws.jpa.management.JPATxEntityManager.getEMInvocationInfo(JPATxEntityManager.java:179)
at
com.ibm.ws.jpa.management.JPAEntityManager.createQuery(JPAEntityManager.java:299)
What I need, is to provide DataSource resource mapping in any of the EJB's using the EntityManager:
#Resource(name = "java:comp/env/jdbc/MYAPP/DS001", lookup = "jdbc/MYAPP/DS001", shareable = true, authenticationType = Resource.AuthenticationType.CONTAINER)
private DataSource ds;
This is very unelegant solution for me, because:
It's very confusing. It need to be declared only once, in any of the EJB's that are using #PersistenceContext. That DataSource may not be used at all in the Java code, and in my case it is not used. It will be hard to understand what that declaration is doing in that file, and why it is only in one file.
It's duplicating the configuration, that is provided in the other place. I need to specify the name of the resource once again (it was already specified in persistance.xml).
It's storing of the configuration in the source code. Quite a dirty anti-pattern.
Technically, it requires javax.annotation.Resource from Java 7, while my project is using Java 6. But the WebSphere runtime hat altered version of that annotation, so everything is working, but requires compiling with javac from WebSphere runtime, instead of standard JDK.
Is it possible to get rid of that annotation? What do I need to use as alternative?
The java:comp/env/ format represents a resource reference, so somehow you must define it. You have a few options to not define a dummy data source:
1.Define a resource at the class level - this is fully supported in Java 6 - and it correctly defines a resource reference:
#Resource(name="jdbc/dsRef", type=javax.sql.DataSource.class, lookup="jdbc/DS")
public class MyBean implements MyBeanLocal {
One more clarification to this and your code - in name you actually should just give a reference name (without java:comp/env) and then in persistence.xml you put java:comp/env/refName. Lookup defines the actual JNDI name registered on the server. You may skip defining a lookup and bind the reference to a resource during installation or via a binding file.
2.Use deployment descriptor
Create a deployment descriptor (web.xml or ejb-jar.xml) and define a resource reference for each EJB there. You will no longer have to place a DataSource with #Resource in your class.
3.Not use reference at all
Although I'd not recommend it, you can use an actual server JNDI datasource name in persistence.xml. Then you don't need a DataSource in an EJB as no reference is used.
<jta-data-source>jdbc/MYAPP/DS001</jta-data-source>
But in that case, you will not see in the admin console that the application is using a DataSource and you will not be able to change that mapping to a different data source jndi name if needed.
And in clarification of your comment:
Technically, it requires javax.annotation.Resource from Java 7, while
my project is using Java 6. But the WebSphere runtime hat altered
version of that annotation, so everything is working, but requires
compiling with javac from WebSphere runtime, instead of standard JDK
javax.annotation.Resource is a part of Java EE 6, which is implemented by WebSphere. You don't need Java v7, but a fully complaint Java EE 6 application server. You are creating a Java EE app not a Java SE one. That's why you need container classes to resolve that annotation. Its nothing 'altered' by WebSphere, just following the specification.

OpenJPA in OSGi not finding MySQL JDBC Connector Bundle

I am currently working on an OSGi project on Felix (v4.0.3). I need to use JPA so I have installed the Apache Aries JPA bundles. I also installed OpenJPA and I need it to connect to a MySQL Database, using the MySQL Connector Bundle. Unfortunately it does not work, OpenJPA says it cannot find the MySQL JDBC class and I cannot figure out what's broken, maybe I am doing something wrong. I'll explain below what I installed precisely along with the persistence.xml file and the actual exception I get.
Here's the list of the Apache Aries bundles I installed :
org.apache.aries.jpa.api-0.3.jar
org.apache.aries.jpa.container.context-0.3.jar
org.apache.aries.jpa.container-0.3.jar
org.apache.aries.util-0.4.jar
I then installed the dependencies of those Apache Aries JPA bundles. I downloaded them from Springsource :
com.springsource.javax.transaction-1.1.0.jar
com.springsource.org.apache.log4j-1.2.16.jar
com.springsource.slf4j.api-1.6.1.jar
com.springsource.slf4j.log4j-1.6.1.jar
javax.persistence_2.0.4.v201112161009.jar (this one is from EclipseLink in case it matters)
I also installed OpenJPA and all its dependencies. I found bundles 2 to 5 (commons-*) in the lib folder of the apache-openjpa-2.2.0 downloaded folder. I downloaded Serp here because the jar found in the lib folder wasn't an OSGi bundle. Finally I found the last two bundles (#7 and #8) in Springsource :
openjpa-2.2.0.jar
commons-collections-3.2.1.jar
commons-dbcp-1.4.jar
commons-lang-2.4.jar
commons-pool-1.5.4.jar
org.apache.servicemix.bundles.serp-1.13.1_4.jar
com.springsource.javax.servlet-2.5.0.jar
com.springsource.org.objectweb.asm-3.2.0.jar
Once I finally had OpenJPA installed, I still needed the MySQL JDBC Driver bundle, which I also got from the Springsource repository along with its commons-logging dependency :
com.springsource.com.mysql.jdbc-5.1.6.jar
com.springsource.org.apache.commons.logging-1.1.1.jar
Now at this point the list of bundles installed is getting quite large. I said I installed OpenJPA but it's only because I could not figure out how to use any other provider with Aries. I initially wanted to use EclipseLink but apparently Apache Aries does not detect it as a provider and according to this blog you have to make yet another bundle containing your own activator for Aries to notice EclipseLink. I tried it but it didn't work so I fell back on using OpenJPA instead.
So now I have two questions :
How can I make OpenJPA notice my MySQL Bundle ?
OR alternatively :
How can I make Apache Aries notice EclipseLink ?
Here's the persistence.xml file I use :
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="userManager.model" transaction-type="RESOURCE_LOCAL">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<class>org.project.dao.entity.UserEntity</class>
<properties>
<property name="openjpa.ConnectionDriverName" value="com.mysql.jdbc.Driver" />
<property name="openjpa.ConnectionURL" value="jdbc:mysql://localhost:3306/usermanager?autoReconnect=true" />
<property name="openjpa.ConnectionUserName" value="root" />
<property name="openjpa.ConnectionPassword" value="root" />
</properties>
</persistence-unit>
</persistence>
The error occurs when the following Constructor of my DAO class is executed :
#PersistenceContext(unitName="userManager.model")
private EntityManager em;
private EntityManagerFactory emf;
public UserDAOBean() {
em = emf.createEntityManager();
}
Here's the error I get with OpenJPA not finding MySQL. Of course it is worth mentioning that both the URL and the username/password do work :
<openjpa-2.2.0-r422266:1244990 nonfatal general error> org.apache.openjpa.persistence.PersistenceException: There were errors initializing your configuration: <openjpa-2.2.0-r422266:1244990 fatal user error> org.apache.openjpa.util.UserException: A connection could not be obtained for driver class "com.mysql.jdbc.Driver" and URL "jdbc:mysql://localhost:3306/usermanager?autoReconnect=true". You may have specified an invalid URL.
at org.apache.openjpa.jdbc.schema.DataSourceFactory.newConnectException(DataSourceFactory.java:255)
at org.apache.openjpa.jdbc.schema.DataSourceFactory.newDataSource(DataSourceFactory.java:123)
at org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl.createConnectionFactory(JDBCConfigurationImpl.java:844)
at org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl.getConnectionFactory(JDBCConfigurationImpl.java:732)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.openjpa.lib.conf.ConfigurationImpl.instantiateAll(ConfigurationImpl.java:295)
at org.apache.openjpa.conf.OpenJPAConfigurationImpl.instantiateAll(OpenJPAConfigurationImpl.java:1671)
at org.apache.openjpa.kernel.AbstractBrokerFactory.makeReadOnly(AbstractBrokerFactory.java:646)
at org.apache.openjpa.kernel.AbstractBrokerFactory.newBroker(AbstractBrokerFactory.java:203)
at org.apache.openjpa.kernel.DelegatingBrokerFactory.newBroker(DelegatingBrokerFactory.java:156)
at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:227)
at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:154)
at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:60)
at org.apache.aries.jpa.container.impl.CountingEntityManagerFactory.createEntityManager(CountingEntityManagerFactory.java:64)
at javax.persistence.EntityManagerFactory$$Proxy.createEntityManager(Unknown Source)
I've cut the exception (it keeps going on and on) until this point :
Caused by: java.lang.ClassNotFoundException: com.mysql.jdbc.Driver not found by org.apache.openjpa [12]
at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1460)
at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:72)
at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1843)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:169)
at org.apache.openjpa.jdbc.schema.DataSourceFactory.newDataSource(DataSourceFactory.java:85)
... 108 more
PS: I couldn't post the links to Aries, OpenJPA or EclipseLink because of the spam restriction, sorry :/
Thanks to Holly Cummins and after another bunch of hours of research, I've been able to find a solution to my problem. I'll detail it below, this is going to be a very long answer.
If you want to use EclipseLink with Apache Aries (which I find orders of magnitude simpler to install than OpenJPA for OSGi because it's contained in only 5 bundles), you will have to checkout the EclipseLink - Aries adapter directly from apache because it has not been released yet.
Go to an appropriate folder and execute the following command to get it :
svn checkout https://svn.apache.org/repos/asf/aries/trunk/jpa/jpa-container-eclipselink-adapter/
You should get a folder named jpa-container-eclipselink-adapter. Now, assuming that you are using Linux and have Maven installed, run the following commands :
cd jpa-container-eclipselink-adapter
mvn clean install
Once Maven has successfully compiled the source of the adapter, you will find it in your Maven repository using the path
<maven-repo>/org/apache/aries/jpa/org.apache.aries.jpa.eclipselink.adapter/0.3.1-SNAPSHOT/org.apache.aries.jpa.eclipselink.adapter-0.3.1-SNAPSHOT.jar
You'll have to deploy this bundle with the others (copying it in the bundle folder for Felix).
So that was for the EclipseLink part, now in order to make your persistence actually work you'll have to use Blueprint with Aries. Here is the list of all the bundles you'll need to get from the [http://aries.apache.org/downloads/currentrelease.html](Apache Aries download page)
org.apache.aries.blueprint
org.apache.aries.proxy
org.apache.aries.jndi.api
org.apache.aries.jndi
org.apache.aries.blueprint
org.apache.aries.jpa.api
org.apache.aries.jpa.container.context
org.apache.aries.jpa.container
org.apache.aries.transaction.blueprint
org.apache.aries.transaction.manager (This one is listed twice on their site, it's just a duplicate)
org.apache.aries.util
Once you're done downloading Aries, you still need dependencies (get them from SpringSource). These are the bundles for SLF4J, Log4J, SLF4J Log4J Binding and javax.transaction 1.1 API.
http://ebr.springsource.com/repository/app/bundle/version/detail?name=com.springsource.slf4j.api&version=1.6.1
http://ebr.springsource.com/repository/app/bundle/version/detail?name=com.springsource.slf4j.log4j&version=1.6.1
http://ebr.springsource.com/repository/app/bundle/version/detail?name=com.springsource.javax.transaction&version=1.1.0
http://ebr.springsource.com/repository/app/bundle/version/detail?name=com.springsource.org.apache.log4j&version=1.2.16
You'll also need the bundles from EclipseLink (you need the OSGi bundle version)
http://www.eclipse.org/eclipselink/downloads/
Open the zip and get the following files :
org.eclipse.persistence.antlr
org.eclipse.persistence.asm
org.eclipse.persistence.core
org.eclipse.persistence.jpa
javax.persistence
Finally, assuming that you want to use a MySQL database, you'll need the bundles for the MySQL JDBC Driver (downloaded from Springsource)
http://ebr.springsource.com/repository/app/bundle/version/detail?name=com.springsource.com.mysql.jdbc&version=5.1.6
http://ebr.springsource.com/repository/app/bundle/version/detail?name=com.springsource.org.apache.commons.logging&version=1.1.1
Once you have all those bundles installed, you need to use a non-jta-datasource that you will get through JNDI. Here's a persistence.xml file that you can change for your needs :
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="userManager" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<non-jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=jdbc/userManagerDS)</non-jta-data-source>
<class>com.example.dao.entity.UserEntity</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<!-- EclipseLink should create the database schema automatically -->
<!-- <property name="eclipselink.ddl-generation" value="create-tables" />
<property name="eclipselink.ddl-generation.output-mode" value="database" /> -->
</properties>
</persistence-unit>
</persistence>
See the javax.sql.Datasource in the non-jta-data-source tag ? That's what we'll define using Blueprint xml.
In order to do so, you'll first need to add the OSGI-INF/blueprint/ folders in your persistence bundle (the one containing your DAOs and Entities). This is the default folder where blueprint xml files are located, any xml file located here will be scanned. Once that's done, create the blueprint.xml file (the name can be changed) and paste (and modify) the following code :
<bean id="dataSource" class="com.mysql.jdbc.jdbc2.optional.MysqlDataSource">
<property name="url" value="jdbc:mysql://localhost:3306/usermanager?autoReconnect=true" />
<property name="user" value="root" />
<property name="password" value="root" />
</bean>
<service id="MySQLDataSource" interface="javax.sql.DataSource" ref="dataSource">
<service-properties>
<entry key="osgi.jndi.service.name" value="jdbc/userManagerDS" />
</service-properties>
</service>
<service id="userDAOService" interface="com.example.dao.remote.UserDAORemote">
<bean class="com.example.dao.beans.UserDAOBean">
<jpa:unit index="0" unitname="userManager" />
</bean>
</service>
</blueprint>
Here, we are doing two things. First, we tell Aries to create the userManagerDS datasource and configure it with the JDBC Driver, URL, user and password. This is the same datasource that we used in the persistence.xml file.
Then, we inject the EntityManagerFactory in our DAO. Our DAO is the com.example.dao.beans.UserDAOBean class, we need to add its name to the bean tag. This class will have to implement an interface and we'll need to add this interface to the service tag. Now the final jpa:unit tag tells Aries to inject the EntityManagerFactory related to the persistence unit called userManager (the same name we used in the persistence.xml) by using the first constructor of UserDAOBean. This is done by using the index="0" attribute. This also means you have to have some code like the following in your DAO :
private EntityManager em;
private EntityManagerFactory emf;
public UserDAOBean(EntityManagerFactory emf) {
this.emf = emf;
this.em = emf.createEntityManager();
}
It's also possible to inject the EMF using a setter. Here are further resources to help you use Blueprint :
http://aries.apache.org/modules/jpaproject.html
http://aries.apache.org/modules/blueprint.html
http://mail-archives.apache.org/mod_mbox/aries-user/201104.mbox/%3C15F2C30E-2A71-4320-9992-DBCF181B58E4#gmail.com%3E
Optional : Be careful, if you are using Felix, adding the javax.transaction bundle will cause a "uses constraint violation" because the system bundle (bundle 0) also exports this API. You'll have to keep it from exporting it by changing the following line in the config.properties :
#org.osgi.framework.system.packages=
You'll have to put in here the list of all the packages that the previous bundle exported. Unfortunately, there's no way to "remove" a package, you have to redefine the entire list of packages to be exported. Here's mine, I hope it helps (yes it is very, very long) :
org.osgi.framework.system.packages=org.osgi.framework;version=1.6.0, org.osgi.framework.launch;version=1.0.0, org.osgi.framework.wiring;version=1.0.0, org.osgi.framework.startlevel;version=1.0.0, org.osgi.framework.hooks.bundle;version=1.0.0, org.osgi.framework.hooks.resolver;version=1.0.0, org.osgi.framework.hooks.service;version=1.1.0, org.osgi.framework.hooks.weaving;version=1.0.0, org.osgi.service.packageadmin;version=1.2.0, org.osgi.service.startlevel;version=1.1.0, org.osgi.service.url;version=1.0.0, org.osgi.util.tracker;version=1.5.0, javax.accessibility;version=0.0.0.1_006_JavaSE, javax.activation;version=0.0.0.1_006_JavaSE, javax.activity;version=0.0.0.1_006_JavaSE, javax.annotation.processing;version=0.0.0.1_006_JavaSE, javax.annotation;version=0.0.0.1_006_JavaSE, javax.crypto.interfaces;version=0.0.0.1_006_JavaSE, javax.crypto.spec;version=0.0.0.1_006_JavaSE, javax.crypto;version=0.0.0.1_006_JavaSE, javax.imageio.event;version=0.0.0.1_006_JavaSE, javax.imageio.metadata;version=0.0.0.1_006_JavaSE, javax.imageio.plugins.bmp;version=0.0.0.1_006_JavaSE, javax.imageio.plugins.jpeg;version=0.0.0.1_006_JavaSE, javax.imageio.spi;version=0.0.0.1_006_JavaSE, javax.imageio.stream;version=0.0.0.1_006_JavaSE, javax.imageio;version=0.0.0.1_006_JavaSE, javax.jws.soap;version=0.0.0.1_006_JavaSE, javax.jws;version=0.0.0.1_006_JavaSE, javax.lang.model.element;version=0.0.0.1_006_JavaSE, javax.lang.model.type;version=0.0.0.1_006_JavaSE, javax.lang.model.util;version=0.0.0.1_006_JavaSE, javax.lang.model;version=0.0.0.1_006_JavaSE, javax.management.loading;version=0.0.0.1_006_JavaSE, javax.management.modelmbean;version=0.0.0.1_006_JavaSE, javax.management.monitor;version=0.0.0.1_006_JavaSE, javax.management.openmbean;version=0.0.0.1_006_JavaSE, javax.management.relation;version=0.0.0.1_006_JavaSE, javax.management.remote.rmi;version=0.0.0.1_006_JavaSE, javax.management.remote;version=0.0.0.1_006_JavaSE, javax.management.timer;version=0.0.0.1_006_JavaSE, javax.management;version=0.0.0.1_006_JavaSE, javax.naming.directory;version=0.0.0.1_006_JavaSE, javax.naming.event;version=0.0.0.1_006_JavaSE, javax.naming.ldap;version=0.0.0.1_006_JavaSE, javax.naming.spi;version=0.0.0.1_006_JavaSE, javax.naming;version=0.0.0.1_006_JavaSE, javax.net.ssl;version=0.0.0.1_006_JavaSE, javax.net;version=0.0.0.1_006_JavaSE, javax.print.attribute.standard;version=0.0.0.1_006_JavaSE, javax.print.attribute;version=0.0.0.1_006_JavaSE, javax.print.event;version=0.0.0.1_006_JavaSE, javax.print;version=0.0.0.1_006_JavaSE, javax.rmi.CORBA;version=0.0.0.1_006_JavaSE, javax.rmi.ssl;version=0.0.0.1_006_JavaSE, javax.rmi;version=0.0.0.1_006_JavaSE, javax.script;version=0.0.0.1_006_JavaSE, javax.security.auth.callback;version=0.0.0.1_006_JavaSE, javax.security.auth.kerberos;version=0.0.0.1_006_JavaSE, javax.security.auth.login;version=0.0.0.1_006_JavaSE, javax.security.auth.spi;version=0.0.0.1_006_JavaSE, javax.security.auth.x500;version=0.0.0.1_006_JavaSE, javax.security.auth;version=0.0.0.1_006_JavaSE, javax.security.cert;version=0.0.0.1_006_JavaSE, javax.security.sasl;version=0.0.0.1_006_JavaSE, javax.sound.midi.spi;version=0.0.0.1_006_JavaSE, javax.sound.midi;version=0.0.0.1_006_JavaSE, javax.sound.sampled.spi;version=0.0.0.1_006_JavaSE, javax.sound.sampled;version=0.0.0.1_006_JavaSE, javax.sql.rowset.serial;version=0.0.0.1_006_JavaSE, javax.sql.rowset.spi;version=0.0.0.1_006_JavaSE, javax.sql.rowset;version=0.0.0.1_006_JavaSE, javax.sql;version=0.0.0.1_006_JavaSE, javax.swing.border;version=0.0.0.1_006_JavaSE, javax.swing.colorchooser;version=0.0.0.1_006_JavaSE, javax.swing.event;version=0.0.0.1_006_JavaSE, javax.swing.filechooser;version=0.0.0.1_006_JavaSE, javax.swing.plaf.basic;version=0.0.0.1_006_JavaSE, javax.swing.plaf.metal;version=0.0.0.1_006_JavaSE, javax.swing.plaf.multi;version=0.0.0.1_006_JavaSE, javax.swing.plaf.synth;version=0.0.0.1_006_JavaSE, javax.swing.plaf;version=0.0.0.1_006_JavaSE, javax.swing.table;version=0.0.0.1_006_JavaSE, javax.swing.text.html.parser;version=0.0.0.1_006_JavaSE, javax.swing.text.html;version=0.0.0.1_006_JavaSE, javax.swing.text.rtf;version=0.0.0.1_006_JavaSE, javax.swing.text;version=0.0.0.1_006_JavaSE, javax.swing.tree;version=0.0.0.1_006_JavaSE, javax.swing.undo;version=0.0.0.1_006_JavaSE, javax.swing;version=0.0.0.1_006_JavaSE, javax.tools;version=0.0.0.1_006_JavaSE, javax.transaction.xa;version=0.0.0.1_006_JavaSE, javax.transaction;version=0.0.0.1_006_JavaSE, javax.xml.bind.annotation.adapters;version=0.0.0.1_006_JavaSE, javax.xml.bind.annotation;version=0.0.0.1_006_JavaSE, javax.xml.bind.attachment;version=0.0.0.1_006_JavaSE, javax.xml.bind.helpers;version=0.0.0.1_006_JavaSE, javax.xml.bind.util;version=0.0.0.1_006_JavaSE, javax.xml.bind;version=0.0.0.1_006_JavaSE, javax.xml.crypto.dom;version=0.0.0.1_006_JavaSE, javax.xml.crypto.dsig.dom;version=0.0.0.1_006_JavaSE, javax.xml.crypto.dsig.keyinfo;version=0.0.0.1_006_JavaSE, javax.xml.crypto.dsig.spec;version=0.0.0.1_006_JavaSE, javax.xml.crypto.dsig;version=0.0.0.1_006_JavaSE, javax.xml.crypto;version=0.0.0.1_006_JavaSE, javax.xml.datatype;version=0.0.0.1_006_JavaSE, javax.xml.namespace;version=0.0.0.1_006_JavaSE, javax.xml.parsers;version=0.0.0.1_006_JavaSE, javax.xml.soap;version=0.0.0.1_006_JavaSE, javax.xml.stream.events;version=0.0.0.1_006_JavaSE, javax.xml.stream.util;version=0.0.0.1_006_JavaSE, javax.xml.stream;version=0.0.0.1_006_JavaSE, javax.xml.transform.dom;version=0.0.0.1_006_JavaSE, javax.xml.transform.sax;version=0.0.0.1_006_JavaSE, javax.xml.transform.stax;version=0.0.0.1_006_JavaSE, javax.xml.transform.stream;version=0.0.0.1_006_JavaSE, javax.xml.transform;version=0.0.0.1_006_JavaSE, javax.xml.validation;version=0.0.0.1_006_JavaSE, javax.xml.ws.handler.soap;version=0.0.0.1_006_JavaSE, javax.xml.ws.handler;version=0.0.0.1_006_JavaSE, javax.xml.ws.http;version=0.0.0.1_006_JavaSE, javax.xml.ws.soap;version=0.0.0.1_006_JavaSE, javax.xml.ws.spi;version=0.0.0.1_006_JavaSE, javax.xml.ws.wsaddressing;version=0.0.0.1_006_JavaSE, javax.xml.ws;version=0.0.0.1_006_JavaSE, javax.xml.xpath;version=0.0.0.1_006_JavaSE, javax.xml;version=0.0.0.1_006_JavaSE, org.ietf.jgss;version=0.0.0.1_006_JavaSE, org.omg.CORBA.DynAnyPackage;version=0.0.0.1_006_JavaSE, org.omg.CORBA.ORBPackage;version=0.0.0.1_006_JavaSE, org.omg.CORBA.TypeCodePackage;version=0.0.0.1_006_JavaSE, org.omg.CORBA.portable;version=0.0.0.1_006_JavaSE, org.omg.CORBA;version=0.0.0.1_006_JavaSE, org.omg.CORBA_2_3.portable;version=0.0.0.1_006_JavaSE, org.omg.CORBA_2_3;version=0.0.0.1_006_JavaSE, org.omg.CosNaming.NamingContextExtPackage;version=0.0.0.1_006_JavaSE, org.omg.CosNaming.NamingContextPackage;version=0.0.0.1_006_JavaSE, org.omg.CosNaming;version=0.0.0.1_006_JavaSE, org.omg.Dynamic;version=0.0.0.1_006_JavaSE, org.omg.DynamicAny.DynAnyFactoryPackage;version=0.0.0.1_006_JavaSE, org.omg.DynamicAny.DynAnyPackage;version=0.0.0.1_006_JavaSE, org.omg.DynamicAny;version=0.0.0.1_006_JavaSE, org.omg.IOP.CodecFactoryPackage;version=0.0.0.1_006_JavaSE, org.omg.IOP.CodecPackage;version=0.0.0.1_006_JavaSE, org.omg.IOP;version=0.0.0.1_006_JavaSE, org.omg.Messaging;version=0.0.0.1_006_JavaSE, org.omg.PortableInterceptor.ORBInitInfoPackage;version=0.0.0.1_006_JavaSE, org.omg.PortableInterceptor;version=0.0.0.1_006_JavaSE, org.omg.PortableServer.CurrentPackage;version=0.0.0.1_006_JavaSE, org.omg.PortableServer.POAManagerPackage;version=0.0.0.1_006_JavaSE, org.omg.PortableServer.POAPackage;version=0.0.0.1_006_JavaSE, org.omg.PortableServer.ServantLocatorPackage;version=0.0.0.1_006_JavaSE, org.omg.PortableServer.portable;version=0.0.0.1_006_JavaSE, org.omg.PortableServer;version=0.0.0.1_006_JavaSE, org.omg.SendingContext;version=0.0.0.1_006_JavaSE, org.omg.stub.java.rmi;version=0.0.0.1_006_JavaSE, org.w3c.dom.bootstrap;version=0.0.0.1_006_JavaSE, org.w3c.dom.events;version=0.0.0.1_006_JavaSE, org.w3c.dom.ls;version=0.0.0.1_006_JavaSE, org.w3c.dom;version=0.0.0.1_006_JavaSE, org.xml.sax.ext;version=0.0.0.1_006_JavaSE, org.xml.sax.helpers;version=0.0.0.1_006_JavaSE, org.xml.sax;version=0.0.0.1_006_JavaSE
You may have better luck using a JNDI datasource rather than a direct jdbc connection. The Aries blog sample has a blog.datasource bundle which registers a datasource using Blueprint. The list of required bundles is longer than what you currently have, but you can just copy them all from the blog-assembly/target directory or pom.xml.
Alternatively, Aries have an org.apache.aries.jpa.eclipselink.adapter which does the same thing as the article you linked to. Aries use it for testing against EclipseLink, so it definitely should work. You could also look at the Aries tests to see how it's used and see if there's an EclipseLink test you can copy.
Things may be easier when using the gemini blueprint dbAccess plugin (http://www.eclipse.org/gemini/dbaccess/) , which I think will work for Aries as well. For MySQL be sure to include the connector plugin (e.g. http://ebr.springsource.com/repository/app/bundle/version/detail?name=com.springsource.com.mysql.jdbc&version=5.1.6). This should be sufficient to get the database up and running, provided the blueprint.xml (to use the example above) is configured properly, as above.

GWT with JPA - no persistence provider

GWT with JPA
There are two projects in my eclipse workspace, let's name them:
-JPAProject
-GWTProject
JPAProject contains JPA configuration stuff (persistence.xml, entity classes and so on). GWTProject is an examplary GWT project (taken from official GWT tutorial).
Both projects work fine alone. That is, I can create EMF (EntityManagerFactory) in JPAProject and get entities from the database. GWTProject works fine too, I can run it, fill the field text in the browser and get the response.
My goal is to call JPAProject from GWTProject to get entities. But the problem is that when calling DAO, I get the following exception:
[WARN] Server class 'com.emergit.service.dao.profile.ProfileDaoService' could not be found in the web app, but was found on the system classpath
[WARN] Adding classpath entry 'file:/home/maliniak/workspace/emergit/build/classes/' to the web app classpath for this session
[WARN] /gwttest/greet
javax.persistence.PersistenceException: No Persistence provider for EntityManager named emergitPU
at javax.persistence.Persistence.createEntityManagerFactory(Unknown Source)
at javax.persistence.Persistence.createEntityManagerFactory(Unknown Source)
at com.emergit.service.dao.profile.JpaProfileDaoService.<init>(JpaProfileDaoService.java:19)
at pl.maliniak.server.GreetingServiceImpl.<init>(GreetingServiceImpl.java:21)
...
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:488)
[ERROR] 500 - POST /gwttest/greet (127.0.0.1) 3812 bytes
I guess that the warnings at the beginning can be omitted for now.
Do you have any ideas? I guess I am missing some basic point. All hints are highly appreciated.
Update: My persistence provider is well defined, the JPA project works well by itself.
I guess it's classpath related problem too. When running the GWT project, in WEB-INF/lib there is only gwt-servlet.jar.
Do you think that making custom Ant file to build whole thing up is the only solution (i.e. make jar out of the JPA project and copying it to WEB-INF/lib)? Or is there any Eclipse solution, so I could set the GWT project properties properly so GWT project would know to include persistence.xml file?
Update: OK, I got it working. I tried to put persitence.xml everywhere in war/WEB-INF where it was possible, but kept getting 'no persistence provider' error. It turned out that it wasn't about persistence.xml. I didn't copy the eclipselink jar to WEB-INF/lib, so it couldn't find provider class defined in persistence.xml. Copying all the jars did the thing.
Thank you very much Pascal.
Struggling a lot with the same error message, I solved the problem with copying all jars (eclipselink.jar, eclipselink-jpa-modelgen_2.1.0.v20100614-r7608.jar, javax.persistence_1.0.0.jar, javax.persistence_2.0.1.v201006031150.jar) from the EclipseLink zip to the .../war/WEB-INF/lib folder of my GWT project to make everything available for the Jetty in hosted mode.
As you can see from the list of files, I was using EclipseLink 2.1. Please adapt this list to your JPA implementation, if necessary.
Hoping, that this may help you as well.
Do you have a persistence provider declared in your persistence.xml? Something like this (I'm using Hibernate here, adapt it to whatever persistence provider you're using):
<persistence
<persistence-unit name="emergitPU" transaction-type="...">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
...
</persistence-unit>
</persistence>
If you do, then I suspect a classpath problem. Did you package the JPA project correctly in the webapp i.e. in WEB-INF/lib?

Hibernate/JPA Annotations -- Unknown Entity

An application that has been working well for months has stopped picking up the JPA #Entity annotations that have been a part of it for months. As my integration tests run I see dozens of "org.hibernate.MappingException: Unknown entity: com.whatever.OrderSystem" type errors.
It isn't clear to me what's gone wrong here.
I have no hibernate.cfg.xml file because I'm using the Hibernate Entity Manager. Since I'm exclusively using annotations, there are no .hbm.xml files for my entities. My persistence.xml file is minimal, and lives in META-INF as it is supposed to.
I'm obviously missing something but can't put my finger on it.
I'm using hibernate-annotations 3.2.1, hibernate-entitymanager 3.2.1, persistence-api 1.0 and hibernate 3.2.1. hibernate-commons-annotations is also a part of the project's POM but I don't know if that's relevant.
Is there a web.xml entry that has vanished, or a Spring configuration entry that has accidentally been deleted?
verify in your entity classe that you import javax.persistent.Entity and not org.hibernate.annotations.Entity
I seem to recall I had a similar issue at one time.
Its a long shot, but if you're not already doing this, have you explicitly specified the provider you are using?
<persistence ...>
<persistence-unit ...>
<provider>org.hibernate.ejb.HibernatePersistence</provider> <---- explicit setting
....
</persistence-unit>
</persistence>
Otherwise, I'm not sure?
Is this happening for one specific class (few classes) or all the entity classes. The persistence.xml file has a list of class and or jar files that need to be scanned for #Entity mappings. If it was working earlier you can do a quick diff with the version of persistence.xml that was working correctly. Another issue could be that it is picking up a different persistence.xml file - you can verify this by introducing an error (for e.g., make the xml invalid) in the persistence.xml.

Categories