We have a project that have quite a lot of dependencies. I am confused in Websphere resource binding and resource definition at all now.
ejb-jar.xml describes resources.
persistance.xml describes database resources.
We can have web.xml, where we describes resources also.
We can have ibm-web-bnd.xml, where we can have binding for resources.
Lets say, I have a *.jar that has definition of data source in persistance.xml (jta-data-source), same data source in ejb-jar.xml (enterprise-beans/session/resource-ref), and also has binding for this data source ibm-web-bnd.xml (resource-ref).
Now I want to use this *.jar in my *.war.
Lets assume that I have configured all resources on my Websphere Liberty server correctly.
During application start up, I've got following error for this *.jar:
Unable to use JDBC Connection to create Statement
java.sql.SQLException: Unsupported use of GenericConnection. A
GenericConnection is provided during application start when creating an
EntityManagerFactory for a persistence unit which has configured one of its
datasource to be in the component naming context; java:comp/env. During
application start, the component naming context will not exist, and the
correct datasource cannot be determined. When the persistence unit is used,
the proper datasource and connection will be obtained and used.
Questions:
Why my *.jar do not see Data Source, that I have defined on my Websphere Libery (in server.xml)? Do I miss some binding in my *.war?
Why do we describe resources in web.xml? I thought that this is definition of web application, like a servlet mapping, filters, etc.
Why same data source is described in both persistance.xml and ejb-jar.xml (is it not enough with persistance.xml?)?
Does resource binding delay somehow dependency injection?
Code in *.jar that I can't modify, but have to use in my *.war:
ejb-jar.xml
...
<enterprise-beans>
<session id="MyEntityManagerBean">
<ejb-name>MyEntityManagerBean</ejb-name>
<ejb-class>somepackage.MyEntityManagerBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
<resource-ref id="some_id_goes_here">
<res-ref-name>jdbc/my_ds</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
</session>
</enterprise-beans>
...
persistance.xml
<persistence-unit name="MyPersistentUnit" transaction-type="JTA">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>java:comp/env/jdbc/my_ds</jta-data-source>
...
</persistence-unit>
ibm-ejb-jar-bnd.xml
...
<session name="MyEntityManagerBean">
<resource-ref name="jdbc/my_ds" binding-name="jdbc/my_ds"/>
</session>
<session name="MyEntityManagerBean2">
<resource-ref name="jdbc/my_ds" binding-name="jdbc/my_ds"/>
</session>
...
MyEntityManagerBean.java (also same *.jar)
#PersistenceContext(unitName="MyPersistentUnit")
protected EntityManager entityManager;
And problem starts, when I add this *.jar as Maven dependency to my *.war.
Thanks in advance.
Related
I am using WebSphere Liberty 17.0.0.2.
The end product is an ear that contains a jar which is using JPA to access database.
The EntityManager is annotated with #PersistenceContext with persistence unit name defined. In the persistence.xml under appropriate persistence-unit the jta-data-source tag contains datasource name (direct lookup) specified in server.xml. With this setup everything is working fine.
Now need arose that I need to switch from direct lookup to indirect lookup regarding datasource JNDI lookup method. As I understand indirect lookup is something like OS environment variables. I use a name to get the configured value, so I can switch datasources without touching my code to rename JDNI names there.
Switching from direct to indirect I'd need to append 'java:comp/env' in my persistence.xml for the jta-data-source.
How can I connect datasource name with indirect lookup name? I tried to specify it in server.xml using resource-ref tag but with no luck.
The main goal here is to using indirect lookup in the code but be able to change datasources in the applicaton server configuration, so I don't have to change my application when this is happning.
Configuration snippets:
server.xml
<library id="oraclelib">
<jdbcDriver id="oracledriver" libraryRef="oraclelib">
<dataSource jndiName="jdbc/oradb" jdbcDriverRef="oracledriver" id="oradbds">
<resource-ref name="jdbc/oradb" binding-name="jdbc/mydb">
persistence.xml
<jta-data-source>java:comp/env/jdbc/mydb</jta-data-source>
When running this setup a javax.naming.NameNotFoundException is thrown.
Update #1
server.xml after swapping name, binding-name
<?xml version="1.0" encoding="UTF-8"?>
<server description="app server">
<library id="OracleLib">
<fileset dir="/oracle" includes="ojdbc6.jar" />
</library>
<jdbcDriver id="OracleJDBCDriver" libraryRef="OracleLib" />
<dataSource jndiName="jdbc/oradb" jdbcDriverRef="OracleJDBCDriver" id="dbDataSource">
<properties.oracle URL="jdbc:oracle:thin:#//dbhost:port/SID" user="dbuser" password="dbpassword" />
</dataSource>
<application id="Myapp_ear" location="/path/myapp.ear" name="Myapp_ear" type="ear">
<application-bnd>
<resource-ref name="jdbc/mydb" binding-name="jdbc/oradb" />
</application-bnd>
</application>
</server>
jta-data-source is java:comp/env/jdbc/mydb
Solution
It turned out that the bean that was used to get EntityManager was a CDI bean. As it is modified to be an EJB bean, the ejb-jar.xml, ibm-ejb-jar-bnd.xml did the trick.
It should be the other way around:
not
<resource-ref name="jdbc/oradb" binding-name="jdbc/mydb">
but
<resource-ref name="jdbc/mydb" binding-name="jdbc/oradb">
name - is resource ref name, and binding-name is jndi name in the server configuration.
I have a small issue in which my maven project does not have a Target Resource JNDI Name.
A brief overview of this project. I have three java projects:
The Maven Ear, the back end (base livraries) project and the UI project. All of which are maven, have dependencies I need, compile and run with a main app which emulates the WAS.
So far the most relevant help I could find was to make sure I have a ibm-web-bnd.xml
I do have this file as I converted an existing UI project to a maven project. The project looks like this.
In my web.xml I also have
<resource-ref>
<description>
</description>
<res-ref-name>jdbc/DataSource</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
In my ibm-web-bnd.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-bnd
xmlns="http://websphere.ibm.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-web-bnd_1_0.xsd"
version="1.0">
<virtual-host name="default_host" />
<resource-ref name="jdbc/DataSource" binding-name="jdbc/DataSource"/>
As it has been pointed out, I did not ask a question.
My question is how do I set a JNDI Resource Reference for my Maven UI project in WebSphere. I have all the required files and bindings for the project yet I can not run the maven EAR with the UI project in it.
I always get the error:
A resource reference binding could not be found for the jdbc/DataSource resource reference, defined for the codecoverageUI component.
I wonder how can I load an external property of my application running inside Wildfly 9 as WAR, I tried to add a java parameter to Wildfly execution but it seems the application did not recognize the properties.
-Dspring.config.location=file:///C:\Temp\config\application.properties,classpath:application.properties
Is there any way how Spring Boot could read the external property file? I am trying to load and run one Spring Boot application as WAR inside Wildfly.
I'd appreciate any help.
Thanks.
In my linux system i have an entry in the standalone.xml:
<system-properties>
<property name="spring.config.location" value="file:/opt/jboss/wildfly/standalone/configuration/"/>
</system-properties>
I just defined the directory here, so it has to end with an "/".
In the directory "/opt/jboss/wildfly/standalone/configuration/" there is my application.yml.
If your springboot application is running inside Wildfly you don't need to read standalone.xml as an external file.
Get the property value directly with System.getProperty(PROPERTY_NAME);
I know it's a bit late for the answer, but maybe this helps:
Within your deployment-descriptor (web.xml), create environment-variables pointing to the spring config location file, i.e.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
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_3_0.xsd"
version="3.0">
<env-entry>
<env-entry-name>spring.config.location</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>file:[path-to-file]/[your-properties-file]
</env-entry-value>
</env-entry>
</web-app>
Working on Wildfly 25.0.0
I decided to try out Hibernate today, which looks promising, although the setup could be easier. After having found solutions for the first million or so configuration errors I'm now stuck with this one:
Exception in thread "main" javax.persistence.PersistenceException: [PersistenceUnit: manager1] Unable to build EntityManagerFactory
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:915)
(...)
Caused by: org.hibernate.HibernateException: Bean Validation not available in the class path but required in javax.persistence.validation.mode
at org.hibernate.cfg.beanvalidation.BeanValidationIntegrator.applyHibernateListeners(BeanValidationIntegrator.java:281)
at org.hibernate.cfg.beanvalidation.BeanValidationIntegrator.integrate(BeanValidationIntegrator.java:134)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:303)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1750)
at org.hibernate.ejb.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:94)
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:905)
... 5 more
Peristence.xml:
<?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="manager1" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>net.zomis.hibernate.Game</class>
<class>net.zomis.hibernate.TestFields</class>
<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
<validation-mode>CALLBACK</validation-mode>
<properties>
<property name="javax.persistence.validation.mode" value="NONE" />
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
<property name="hibernate.hbm2ddl.auto" value="validate"/>
</properties>
</persistence-unit>
</persistence>
The (as far as I can tell) relevant portions of hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8' ?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
(...)
<property name="hbm2ddl.auto" >validate</property>
<mapping class="net.zomis.hibernate.Game" />
<mapping class="net.zomis.hibernate.TestFields" />
</session-factory>
</hibernate-configuration>
I have tried adding this to the build path without any change. I have googled for Bean Validation not available in the class path but required in javax.persistence.validation.mode and also just Bean Validation not available in the class path. I found the source code, but that doesn't help me much.
I have also tried removing the properties from the xml configuration files, without any luck.
I do not use Maven. I simply use Eclipse and build and run the project directly from Eclipse.
The obvious question is: How can I solve this problem? Do I need an additional jar in my build path that I have missed? (In that case which one?) and also: Why is it needed? Can I change something so that it is not needed anymore?
You need to have the validation-api (there's a download JAR link you can use as you don't use maven) in your classpath.
Hibernate searches for the javax.validation.Validation class in the classpath.
If it doesn't find it it throws the Bean Validation not available in the class path but required in javax.persistence.validation.mode error.
If you're not using maven you need to build up the classpath yourself and it's easy to miss a jar. It might be worthwhile to just use maven to bootstrap your project, and to make sure you have all the jars in place.
If you're using maven, the validation-api is pulled in as a transitive dependency from hibernate-validator.
You need the Hibernate Validator artifact:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.3.1.Final</version>
</dependency>
This will also include the Bean Validation API, which indeed is in this case a requirement as well.
In case you are not using any Bean Validation constraints (e.g. #NotNull, #Before, #Pattern, etc) you could also just remove
<validation-mode>CALLBACK</validation-mode>
or set it to NONE. Bean Validation is not required for Hibernate usage it is just an add-on defined in the JPA specification. If Bean Validation is on the classpath life cycle based validation (validation of entities on pre-update, pre-persist, etc) is automatically enabled (see also http://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/#d0e3096 and of course the JPA 2 specification).
On the other hand, if you don't have Bean Validation on the classpath, but explicitly ask for it via the configuration option in persistence.xml you get the error you describe.
In a Java EE 6 application where I'm using .ear packaging, I'd like to create a persistence unit that can be accessed from components in different .jar files.
However, I'm not sure how to define this persistence unit. With the #PersistenceContext annotation the lookup only succeeds if the name matches a persistence unit defined in the local persistence.xml file.
Is it possible to refer to external persistence units?
Here are the relevant sections of the JPA 2.0 specification:
8.2 Persistence Unit Packaging
...
A persistence unit is defined by a
persistence.xml file. The jar file or
directory whose META-INF directory
contains the persistence.xml file is
termed the root of the persistence
unit. In Java EE environments, the
root of a persistence unit must be one
of the following:
an EJB-JAR file
the WEB-INF/classes directory of a WAR file[80]
a jar file in the WEB-INF/lib directory of a WAR file
a jar file in the EAR library directory
an application client jar file
It is not required that an EJB-JAR or
WAR file containing a persistence unit
be packaged in an EAR unless the
persistence unit contains persistence
classes in addition to those contained
within the EJB-JAR or WAR. See Section
8.2.1.6.
NOTE: Java Persistence 1.0 supported use of a jar file in the root of the
EAR as the root of a persistence unit.
This use is no longer supported.
Portable applications should use the EAR library directory for this case
instead. See [9].
A persistence unit must have a name.
Only one persistence unit of any given
name must be defined within a single
EJB-JAR file, within a single WAR
file, within a single application
client jar, or within an EAR. See
Section 8.2.2, “Persistence Unit
Scope”.
The persistence.xml file may be used
to designate more than one persistence
unit within the same scope.
All persistence classes defined at the
level of the Java EE EAR must be
accessible to all other Java EE
components in the application - i.e.
loaded by the application classloader
- such that if the same entity class is referenced by two different Java EE
components (which may be using
different persistence units), the
referenced class is the same identical
class.
And later:
8.2.2 Persistence Unit Scope
An EJB-JAR, WAR, application client
jar, or EAR can define a persistence
unit.
When referencing a persistence unit
using the unitName annotation
element or persistence-unit-name
deployment descriptor element, the
visibility scope of the persistence
unit is determined by its point of
definition:
A persistence unit that is defined at the level of an EJB-JAR, WAR, or
application client jar is scoped to
that EJB-JAR, WAR, or application jar
respectively and is visible to the
components defined in that jar or war.
A persistence unit that is defined at the level of the EAR is generally
visible to all components in the
application. However, if a persistence
unit of the same name is defined by an
EJB-JAR, WAR, or application jar file
within the EAR, the persistence unit
of that name defined at EAR level will
not be visible to the components
defined by that EJB-JAR, WAR, or
application jar file unless the
persistence unit reference uses the
persistence unit name # syntax to
specify a path name to disambiguate
the reference. When the # syntax is
used, the path name is relative to the
referencing application component jar
file. For example, the syntax
../lib/persistenceUnitRoot.jar#myPersistenceUnit
refers to a persistence unit whose
name, as specified in the name element
of the persistence.xml file, is
myPersistenceUnit and for which the
relative path name of the root of the
persistence unit is
../lib/persistenceUnitRoot.jar. The
# syntax may be used with both the unitName annotation element or
persistence-unit-name deployment
descriptor element to reference a
persistence unit defined at EAR level.
Also you need to include entity classes jar in manifest of pu jar http://wiki.eclipse.org/Packaging_and_Deploying_EclipseLink_JPA_Applications_(ELUG)
To summarize, you should be able to define your entities and the persistence unit at the top level of the EAR and to use them from the other modules.
I'm just not sure to understand what you tried and what problem(s) you faced.
The problem could be solved by placing a persistence.xml in a jar file that is located in the ear's lib directory.
The persistence.xml must contain the jar files which includes the Entities.
I had to give the relative path to the jar files.
My ear irectory structure
|-ear--
|-lib--|... some libs ...
| |--my-persistence-xml.jar
|-ejb-with-entities1.jar
|-ejb-with-entities2.jar
My persistence.xml for jboss 7.1.1
<persistence-unit name="my-pu" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:jboss/datasources/mypu</jta-data-source>
<jar-file>../ejb-with-entities1.jar</jar-file>
<jar-file>../ejb-with-entities1.jar</jar-file>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true" />
</properties>
</persistence-unit>
Hope this helps
All you need
EAR +
|- META-INF +
| - persistence.xml
|- ejb1-module.jar
|- ejb2-module.jar
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<persistence-unit name="my-persistence-unit">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>MyDataSource</jta-data-source>
<!-- Note: it's relative to `persistence-module.jar` file location in EAR -->
<jar-file>../ejb1-module.jar</jar-file>
<jar-file>../ejb2-module.jar</jar-file>
<properties>
...
</properties>
</persistence-unit>
</persistence>
Example working EAR layout for Glassfish:
EAR +
|- lib +
| |- core-module.jar
| \- persistence-module.jar +
| \- META-INF +
| \- persistence.xml
|- ejb1-module.jar
\- ejb2-module.jar
EJB modules may be either jar archives or exploded directories.
In this case your persistence.xml may be like:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<persistence-unit name="my-persistence-unit">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>MyDataSource</jta-data-source>
<!-- Note: it's relative to `persistence-module.jar` file location in EAR -->
<jar-file>../ejb1-module.jar</jar-file>
<jar-file>../ejb2-module.jar</jar-file>
<properties>
<property name="hibernate.current_session_context_class" value="jta"/>
<property name="hibernate.id.new_generator_mappings" value="true"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL82Dialect"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
</properties>
</persistence-unit>
</persistence>
You have to update <jar-file> references if you use module versioning (e.g. ejb1-module-1.0-SNAPSHOT.jar).
Abstract objects with #MappedSuperclass annotation and EntityManager injection may be placed in any external jar. This jar does not require to be mentioned in persistence.xml. For example, you can create core-module.jar with PersistableEntity.java:
public class PersistableEntity {
#Id
#GeneratedValue
private Long id;
public Long getId() { return id; }
public Integer getVersion() { return version; }
}
And PersistableEntityManager.java:
public class PersistableEntityManager<T extends PersistableEntity> {
#PersistenceContext
protected EntityManager em;
}
This core-module.jar could be used by all your projects with different persistence units.
You just inherit your Entities and EJBs and avoid boilerplate.
Check out example bilionix-core on github.
Try with this:
Configure EAR application.xml file in this way:
http://xmlns.jcp.org/xml/ns/javaee/application_7.xsd"
version="7">
YourEEApplication
<initialize-in-order>true</initialize-in-order> <!-- This is the most important thing -->
<module>
<ejb>YourEJBModule1.jar</ejb>
</module>
<module>
<ejb>YourEJBModule2.jar</ejb>
</module>
......
<module>
<ejb>YourEJBModuleX.jar</ejb>
</module>
<module>
<web>
<web-uri>YourWebModule.war</web-uri>
<context-root>YourWebModule</context-root>
</web>
</module>
In your EJB projects YourEJBModule1, YourEJBModule2... and YourEJBModuleX:
Inject Persistence Context whitout the unitName property:
#PersistenceContext(type=PersistenceContextType.TRANSACTION)
private EntityManager em; // get & set
For each EJB module persistence.xml file:
YourEJBModule1:
<?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="PersistenceUnit1"
transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/YourDataSource</jta-data-source>
<class>com.example.Foo1</class>
<!-- Other properties -->
</persistence-unit>
</persistence>
YourEJBModule2:
<?xml version="1.0" encoding="UTF-8"?>
...
<persistence-unit name="PersistenceUnit2"
transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/YourDataSource</jta-data-source>
<jar-file>YourEJBModule1.jar</jar-file>
<class>com.example.Foo2</class>
<!-- Other properties -->
</persistence-unit>
...
YourEJBModuleX:
<?xml version="1.0" encoding="UTF-8"?>
...
<persistence-unit name="PersistenceUnitX"
transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/YourDataSource</jta-data-source>
<jar-file>YourEJBModule1.jar</jar-file>
<jar-file>YourEJBModule2.jar</jar-file>
......
<class>com.example.FooX</class>
<!-- Other properties -->
</persistence-unit>
...
In the database can exists various schemas, one per EJB module, access them through jta-data-source
(Deployed in Glassfish 4)
Here's what I did.
1) Package the persistence configuration files in a jar file. The jar file will contain:
META-INF/persistence.xml (and orm.xml if you use one)
Create a "lib" folder under the EAR project and stick the jar in there
2) Package the associated entity classes in another jar:
Put this jar file in your GlassFish domain/lib folder (or whatever lib folder equiv in other servers)
I initially bundled the jar in the EAR's "lib" folder but classes were not found
If anyone knows a better way to handle this please explain
The Persistence Context should now be accessible to all EJB and Web Apps bundled in your Enterprise Application.
I wanted to achieve shared persistance EJB module without EAR project.
This is possible by
moving all persistance entities to separate EJB project (do not move persistance.xml to new project, only classes are needed
compiling this EJB project
sending project to GlassFish server using
scpAsSudo ~/NetbeansProjects/UnifyEntities/dist/UnifyEntities.jar remoteUsername#192.168.0.1:/opt/glassfish3/domains/domain1/lib/ext
Have fun!