How to map Datasources in Wildfly using deployment descriptors - java

My question is: How do I map a datasource to a specific jndi-name configured inside wildfly so that multiple deployed .war-files each can use their own specific datasource. The mapping should take place at deployment so that a configuration inside wildfly and the specific project is sufficient.
We got a project which supports multi-tenancy. The structure is as follows:
customerSpecificProject
|-- ui (generic)
|----database (generic)
|----services (generic)
|----etc...
In the database-project a standard datasource is specified which goes by a standard jndi-name java:/xyzDS. Since we migrated from tomcat to wildfly we want to make use of the ability to host multiple applications in our AS.
To achieve this we have to map the java:/xyzDS to the datasources defined in the standalone.xml:
<subsystem xmlns="urn:jboss:domain:datasources:4.0">
<datasources>
<datasource jta="true" jndi-name="java:/customer1DS" pool-name="c1DS" enabled="true" use-ccm="true">
...
</datasource>
<datasource jta="true" jndi-name="java:/customer2DS" pool-name="c2DS" enabled="true" use-ccm="true">
...
</datasource>
Therefore we tried to use the jboss-web.xml located in the WEB-INF folder of our customerProject:
<?xml version="1.0" encoding="UTF-8"?>
<jboss-web xmlns="http://www.jboss.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.jboss.com/xml/ns/javaee
http://www.jboss.org/j2ee/schema/jboss-web_5_1.xsd">
<resource-ref>
<res-ref-name>java:/xyzDS</res-ref-name>
<jndi-name>java:/customer1DS</jndi-name>
</resource-ref>
</jboss-web>
persistence.xml inside the database-Project:
<?xml version='1.0' encoding='UTF-8'?>
<persistence version="2.1"
xmlns="http://xmlns.jcp.org/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_1.xsd">
<persistence-unit name="xyzDB" transaction-type="JTA">
<jta-data-source>java:/xyzDS</jta-data-source>
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>...</class>
...
<class>...</class>
<shared-cache-mode>NONE</shared-cache-mode>
<validation-mode>NONE</validation-mode>
<properties>
<property name="eclipselink.weaving" value="static" />
</properties>
</persistence-unit>
</persistence>
It does not seem to be working. I talked to a colleague who had a similar issue and resolved it in the corresponding way for a websphere AS. I do not know if the problem resides in the structure having a nested databaseProject inside another lib (ui) for the actual customerProject or if it is caused by bad configuration.
Also we use the #Resource Annotation inside some DAOs:
#Resource(lookup = "java:/xyzDS")
private DataSource dataSource;
Maybe the mapping works but not for the annotations inside the compiled DAOs? But I do not understand why that should not work.
Current Error in Stacktrace:
11:18:20,839 ERROR [org.jboss.as.controller.management-operation] (DeploymentScanner-threads - 1) WFLYCTL0013: Operation ("full-replace-deployment") failed - address: ([]) - failure description: {
"WFLYCTL0080: Failed services" => {"jboss.deployment.unit.\"xyz.war\".INSTALL" => "org.jboss.msc.service.StartException in service jboss.deployment.unit.\"xyz.war\".INSTALL: WFLYSRV0153: Failed to process phase INSTALL of deployment \"xyz.war\"
Caused by: java.lang.IllegalArgumentException: WFLYEE0047: Incompatible conflicting binding at java:/xyzDS source: lookup (java:/customer1DS)"},
Edit: Already tried adding:
<property name="wildfly.jpa.twophasebootstrap" value="false"/>
To persistence.xml

Have you checked the question/answer in wildfly-development.1055759.n5.nabble.com? In this exchange, it was determined that the persistence unit needed a hint in the form of
<property name="wildfly.jpa.twophasebootstrap" value="false"/>
I don't know if this is applicable in your case, but is worth looking at.

Related

Entities not being detected when using packaged Hibernate JPA persistence provider

Im deploying my web application on a local wildfly-11.0.0.Final
server.
Wildfly however provides its own hibernate and jpa modules which I
dont want to use. I want to use the jpa jars packaged with my
application.
As described in
https://docs.jboss.org/author/display/WFLY10/JPA+Reference+Guide#JPAReferenceGuide-PackagingtheHibernateJPApersistenceproviderwithyourapplication
I added the line
<property name="jboss.as.jpa.providerModule" value="application"/>
to my persistence.xml
Now however my entites (Annotated with #Entity) are not being detected anymore and I have to explicitly name them in my persistence.xml like
<class>com.mycompany.mywebapp.Actor</class>
Is there any way to fix this?
I tried
<jar-file></jar-file>
and
<property name="hibernate.archive.autodetection" value="class, hbm"/>
without success.
My persistence.xml looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="com.mycompany_mywebapp_war_1.0PU" transaction-type="JTA">
<jta-data-source>java:/jboss/sakila</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="jboss.as.jpa.providerModule" value="application"/>
</properties>
</persistence-unit>
</persistence>
Edit:
Im using hibernate 5.3.7.Final which implements jpa 2.2.
My wildfly server provides hibernate 5.1.10.Final with jpa 2.1.
Edit 2:
I noticed that even though the hibernate version is now 5.3.7.Final the jpa provided by wildfly (specification version 2.1) is still being used which may be causing this issue.
I tried disabling the wildfly modules in a jboss-deployment-structure.xml:
<jboss-deployment-structure>
<deployment>
<exclusions>
<module name="org.hibernate" />
<module name="javax.persistence.api" />
</exclusions>
</deployment>
</jboss-deployment-structure>
However now im facing following error:
Cannot upload deployment: {"WFLYCTL0080: Failed services" => {"jboss.deployment.unit.\"webapp-1.0.war\".FIRST_MODULE_USE" => "WFLYSRV0153: Failed to process phase FIRST_MODULE_USE of deployment \"webapp-1.0.war\" Caused by: org.jboss.as.server.deployment.DeploymentUnitProcessingException: WFLYJPA0019: Could not deploy application packaged persistence provider 'org.hibernate.jpa.HibernatePersistenceProvider' Caused by: java.lang.ClassCastException: class org.hibernate.jpa.HibernatePersistenceProvider"}}
Edit 3:
To test whether this is the cause for my initial problem I manually replaced the jpa jar. Unfortunately this doesnt solve my problem.
Anyway I would like to know how I can fix the issue of my packaged jpa jar not being used and how to make my entities be automatically detected again. Any hints?

Configuration of persistence.xml while using websphere 8.5.5.1

I'm coding an app that uses Servlet 3.0, Jsp, and JPA 2.0 and i'm deploying it into Websphere application server 8.5.
Since i already configured into the ibm websphere console, the data source and the jdbc driver, and the j2c authentification (i'm using oracle 11g as a database ). I dont know how my persistence.xml should look like, if i need to specify and add openJPA jars to my project.
For now anything i put into persistence.xml i'm having this issue :
Error 500: <openjpa-2.2.3-SNAPSHOT-r422266:1764177 fatal user error> org.apache.openjpa.persistence.ArgumentException
What should i do ? maybe i'm missing how JPA works
Thanks in advance
The OpenJPA jars should be provided by WebSphere and available to use for your application. There is a JPA sample available here: https://developer.ibm.com/wasdev/downloads/#asset/samples-Java_Persistence_API_JPA_Sample
In the sample, you can see an example of the persistence.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
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">
<persistence-unit name="jpasamplepersistenceunit">
<jta-data-source>java:comp/env/jdbc/samplejpadatasource</jta-data-source>
<non-jta-data-source>java:comp/env/jdbc/samplejpadatasourcenonjta</non-jta-data-source>
<class>wasdev.sample.jpa.Thing</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<!-- These properties are creating the database on the fly. We are using them to avoid users having
to create a database to run the sample.
See also the create=true line in the datasource meta data. -->
<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)" />
<property name="openjpa.jdbc.DBDictionary" value="derby" />
<!-- EclipseLink specific properties to create the database. They are only used if using the jpa-2.1 feature. -->
<property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
<property name="eclipselink.ddl-generation.output-mode" value="both" />
</properties>
</persistence-unit>
</persistence>
I think your error is not caused by the OpenJPA jars not being available. It might be because your database is not configured correctly. Make sure your persistence.xml file refers to your datasources properly.

JavaEE + eclipseLink + TomEE gives java.sql.SQLSyntaxErrorException: user lacks privilege or object not found

I try to make a simple app using a rest service, eclipseLink and mysql.
I want to make this run on a TomEE server (apache-tomee-plume-1.7.4).
I deploy the app with eclipse.
The deployment seems to be ok
When I go to http://localhost:8080/eleve/ I'm getting :
javax.servlet.ServletException: Error processing webservice request
org.apache.tomee.webservices.CXFJAXRSFilter.doFilter(CXFJAXRSFilter.java:98)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
java.io.IOException: Failed to invoke AbstractHTTPDestination
org.apache.openejb.server.cxf.rs.CxfRsHttpListener.doInvoke(CxfRsHttpListener.java:229)
org.apache.tomee.webservices.CXFJAXRSFilter.doFilter(CXFJAXRSFilter.java:94)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
java.lang.RuntimeException: org.apache.cxf.interceptor.Fault:
Internal Exception: java.sql.SQLSyntaxErrorException: user lacks privilege or object not found: ELEVE
Error Code: -5501
Call: SELECT ID, ADRESSE, classe, date_naissance, NOM, PRENOM, SEXE FROM ELEVE
Query: ReadAllQuery(referenceClass=Eleve sql="SELECT ID, ADRESSE, classe, date_naissance, NOM, PRENOM, SEXE FROM ELEVE")
org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:116)
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:324)
org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:240)
org.apache.openejb.server.cxf.rs.CxfRsHttpListener.doInvoke(CxfRsHttpListener.java:227)
org.apache.tomee.webservices.CXFJAXRSFilter.doFilter(CXFJAXRSFilter.java:94)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
Here is my persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0"
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_1_0.xsd">
<persistence-unit name="notePU" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>com.test.eleve.model.Eleve</class>
<properties>
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password" value="" />
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/notes_eleves" />
<!-- <property name="eclipselink.ddl-generation" value="drop-and-create-tables" /> -->
<property name="eclipselink.logging.level" value="INFO" />
</properties>
</persistence-unit>
</persistence>
I must be missing something but I can not find what.
I pushed my code here: gitlab
Thanks for your help
I finally managed to make it works on TomEE 1.7 and 7.
This is the changes I had to do:
Remove the database related properties from the persistence.xml
Replace non-jta-data-source tag by jta-data-source in persistence.xml
Put the mysql connector jar in my server /lib
In my server /conf/tomee.xml I have added myDatasource configuration as a resource.
Put #XmlRootElement(name = "eleve") over my Eleve entity (this seems to be only mandatory on TomEE <7)
At the end I think that my issue was that the datasource needs to be configure in the server conf in a EE context (datasource properties in persistence was just ignore I think, so it was like no one was declared) and the exception
user lacks privilege or object not found
was comming from the fact that:
If a DataSource is needed by the application and one is not declared,
TomEE will create one dynamically using default settings.
TomEE documentation
I'm not 100% sure of that explanation but at least the problem is solved, don't hesitate to put comments if I misunderstood something.
I have updated the gitlab project
Edit: Be aware that you can also configure the resource in a /WEB-INF/resources.xml file
Edit 2: If you are using Eclipse you can also face this issue if you wrongly configured your server location, it should be set to "use Tomcat installation (take control...)" and not "use workspace metadata"

Persistence unit name issue during deployment WildFly

Stuck with some issue with my persistence module.
getting error like "Unexpected problem gathering statistics: java.lang.IllegalStateException: JBAS011477: Persistence unit 'EAR_FileName.ear/EJB_Module_Persistence.jar#MyPersistenceUnit' is not available"
my persistence.xml file is located as highlighted below. please correct me if i am wrong - as per packaging structure persistence unit name starting with EAR file name then my persistence module name then #unit name, which is absolutely right. and i am injecting my persistence unit in another ejb using PersistenceContext.
#PersistenceContext(unitName="MyPersistenceUnit")
private EntityManager em;
could anyone suggest me what wrong i am doing here. i would appreciate any input/help you could provide on this.
here is below module structure of my project
EAR_FileName.ear
|
|---EJB_Module1.jar
|
|---EJB_Module_Persistence.jar
|
|---META-INF
|
|---persistence.xml
Here is my persistence.xml file
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
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">
<persistence-unit name="MyPersistenceUnit" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:/MyTransactionDS</jta-data-source>
<class>all class</class>
<properties>
<property name="hibernate.show_sql" value="false"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.use_sql_comments" value="true"/>
<property name="hibernate.cache.use_second_level_cache" value="true"/>
</properties>
</persistence-unit>
</persistence>
P.S. using WildFly 8.1 as an application server.
thanks in advance.
It looks that there is already a defect at the Wildfly-Tracker for this problem:
WFLY-4908: Redeploy dependent ear fails with duplicate resource error for persistence unit
There is as well a post at the Jboss-Forum:
JBoss-Dev: Redeploy dependent ear fails with duplicate resource error for persistence unit
According to the defect description, the issue is fixed with Wildfly 10.1.0.CR1.

Unable to access datasource remotely through JBoss

Context
I have a JBoss where I have sucessfully deployed a datasource mydatasource-ds.xml.
It's JNDI name is java:mydatasourceDS. JBoss claims that the datasource is succesfully deployed. The JMX console agress too.
Problem
I want to use this datasource from a client java app launched on a separate JVM.
But I get an exception saying the java:mydatasourceDS cannot be found.
java.lang.ClassCastException: javax.naming.Reference cannot be cast to javax.sql.DataSource
Details
Here is the persistence.xml file :
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0"
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_1_0.xsd">
<persistence-unit name="mydatasource-db" transaction-type="JTA">
<jta-data-source>java:mydatasourceDS</jta-data-source>
<properties>
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.default_schema" value="rec" />
<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup"/>
</properties>
</persistence-unit>
Here is the jndi.properties file :
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=jnp://localhost:1099
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
Here is the application classpath :
jndi.properties
log4j.properties
META-INF\persistence.xml
hibernate-jpa-2.0-api-1.0.0.Final.jar
jnp-client-5.0.3.GA.jar
jboss-common-core-2.2.14.GA.jar
jboss-logging-spi-2.1.0.GA.jar
hibernate-entitymanager-3.6.4.Final.jar
hibernate-core-3.6.4.Final.jar
antlr-2.7.6.jar
commons-collections-3.1.jar
dom4j-1.6.1.jar
hibernate-commons-annotations-3.2.0.Final.jar
jta-1.1.jar
javassist-3.12.0.GA.jar
slf4j-api-1.6.1.jar
slf4j-log4j12-1.6.1.jar
log4j-1.2.16.jar
xstream-1.4.1.jar
xmlpull-1.1.3.1.jar
xpp3_min-1.1.4c.jar
EDIT
I have found the source of the problem. The javax.sql.DataSource that was available to my client application was NOT the one received from JNDI. The one I receive from JNDI is the JBoss javax.sql.DataSource. Same name BUT slightly different classes hence the ClassCastException...
As of this writing, the JBoss javax.sql.DataSource can be found in this package : jboss-j2ee-4.2.3.GA.jar
If you get a
javax.naming.Reference
that means you are missing runtime dependencies that are required for it to resolve. You can inspect the classFactory member of the Reference object via
getFactoryClassName()
to figure out the first dependency you are missing.
In my case using JBoss6.1 it was:
org.jboss.resource.adapter.jdbc.remote.DataSourceFactory
Putting the jar this class is in on the classpath (common/lib/jbosscx-client.jar) got me past the first step and then it was a matter of tracking down all the ClassNotFoundException errors.
The full list for JBoss6.1 turned out to be:
- client/jnp-client.jar
- client/jboss-logging.jar
- common/lib/jbosscx-client.jar
- client/concurrent.jar
- client/jboss-client.jar
- client/jboss-common-core.jar
- client/jboss-integration.jar
- client/jboss-remoting.jar
- client/jboss-security-spi.jar
- client/jboss-serialization.jar
- client/jboss-transaction-api_1.1_spec.jar
This guide says that you have to set
<use-java-context>false</use-java-context>
in mydatasource-ds.xml. Not sure if you did.

Categories