I'm new to JPA and Liberty. Could anyone please explain how to relate/link the server.xml, web.xml and persistence.xml configuration to set up the database connection?
your help on this is much appreciated.
In Liberty, you define the location of the JDBC driver jar files and configure a dataSource element with a JNDI name. This knowledge center page contains an example for MySQL,
https://www.ibm.com/support/knowledgecenter/en/SSEQTP_liberty/com.ibm.websphere.wlp.doc/ae/twlp_dep_configuring_ds.html
Directly quoting from the above page,
<dataSource id="DefaultDataSource" jndiName="jdbc/mySQL">
<jdbcDriver libraryRef="MySQLLib"/>
<properties databaseName="SAMPLEDB" serverName="localhost" portNumber="3306"/>
</dataSource>
<library id="MySQLLib">
<file name="C:/mysql-connector-java-x.x.xx/mysql-connector-java-x.x.xx.jar"/>
</library>
After this, you can configure the jta-data-source element in your persistence.xml pointing at the JNDI name that you chose. For example,
...
<persistence-unit name="ExamplePersistenceUnit">
<jta-data-source>jdbc/mySQL</jta-data-source>
</persistence-unit>
The above is sufficient to get it working, without involving web.xml.
The deployment descriptor (web.xml) gives you the option of adding a level of indirection/mapping and the ability to configure some additional settings such as shareability and container vs application authentication. You can do this by defining a resource reference in web.xml pointing to the data source. Resource references have names in java:comp/env, java:module/env, java:app/env or java:global/env that reflect their visibility. I'll use java:module in the following example, meaning that the reference we are defining is only visibility within the same module (the web module that provides the web.xml),
<resource-ref>
<res-ref-name>java:module/env/jdbc/mySQLRef</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
<lookup-name>jdbc/mySQL</lookup-name>
</resource-ref>
After defining the resource reference above, the data source continues to be available at the JNDI name specified in server.xml, but also becomes available via the JNDI name of the resource reference, meaning you could alternately specify,
<jta-data-source>java:module/env/jdbc/mySQLRef</jta-data-source>
Deployment descriptors can also do some more advanced things like defining a data source in place of the server config. However, to keep this answer simple, I've skipped over that possibility.
This IBM KnowledgeCenter topic is a good place to start
Related
When deploying "regular" web apps to Liberty, I was used to binding the global datasource configured in Liberty's server.xml to the individual application by using a child element within the element, like this:
<application context-root="helloApp" location="..." name="helloApp" type="war">
<application-bnd>
<data-source id="db2appDs" name="jdbc/datasource" binding-name="jdbc/theDB"/>
</application-bnd>
...
</application>
<dataSource id="db2ds" jndiName="jdbc/theDB" type="javax.sql.DataSource">
...
</dataSource>
When configuring my first Spring Boot application to deploy to Liberty, I am trying to use the new <springBootApplication> element for it - but I don't seem to be able to add a binding for the datasource I want to use the same way, as this element doesn't seem to support such a child. (It seems to want only <classloader> as a child).
I've seen people suggest I use an #Resource annotation that includes both application-local JDNI name and global JNDI name for the datasorce - but that defeats the purpose, since I don't want to know what the global name is until deploy time.
Is there another way to do this, like we used to before? Or are applications deployed through <springBootApplication> expected to know the global JNDI name of the datasource(s) they want?
Application-defined datasources are not supported for <springBootApplication/>’s. While your application may certainly access a Liberty datasource using its global JNDI name, you should configure the spring.datasource.jndi-name property within your Spring Boot application as described in section 29.1.3 of the Spring Boot features reference. For your example try spring.datasource.jndi-name=jdbc/theDB.
I am trying to add ActiveMQ as a JMS Provider in Websphere Application Server.
I have followed the instructions described here ActiveMQ 5.11 with WebSphere Application Server 8.5 and adapted to the topic.
Unfortunately I am not sure what I need to add in External JNDI name for both Topic Connection Factory and Topic definitions.
As per IBM documentation:
"External JNDI Name The JNDI name that is used to bind the queue into
the application server name space.
As a convention, use the fully qualified JNDI name; for example, in
the form jms/Name, where Name is the logical name of the resource.
This name is used to link the platform binding information. The
binding associates the resources defined by the deployment descriptor
of the module to the actual (physical) resources bound into JNDI by
the platform."
From my understanding this should be the name that I am using in my app to access the resource defined in WAS.
I also have added the resources in my deployment descriptor as resources.
Any help would be highly appreciated.
Regards
Given that you are accessing the resources via resource references (defined in your deployment descriptor), the configured JNDI name should match the lookup name that is defined in your resource reference.
For example, if your resource reference looks like this,
<resource-ref>
<res-ref-name>java:comp/env/jms/topicConnectionFactoryRef</res-ref-name>
<res-type>javax.jms.TopicConnectionFactory</res-type>
<lookup-name>jms/myTopicConnectionFactory</lookup-name>
</resource-ref>
or if your resource-ref lacks lookup-name and you instead have a ibm-web-bnd.xml file with a binding-name,
<resource-ref name="java:comp/env/jms/topicConnectionFactoryRef"
binding-name="jms/myTopicConnectionFactory">
</resource-ref>
then specify jms/myTopicConnectionFactory as the JNDI name.
Application code will then be able to do:
TopicConnectionFactory tcf = InitialContext.doLookup("java:comp/env/jms/topicConnectionFactoryRef");
Application code could also perform a direct lookup of the JNDI name as follows (although using the resource reference is preferred because it is more spec compliant and standard across app servers),
TopicConnectionFactory tcf = InitialContext.doLookup("jms/myTopicConnectionFactory");
The same applies to javax.jms.Topic.
If your resource environment reference in your deployment descriptor looks like this,
<resource-env-ref>
<resource-env-ref-name>java:comp/env/jms/topicRef</resource-env-ref-name>
<resource-env-ref-type>javax.jms.Topic</resource-env-ref-type>
<lookup-name>jms/myTopic</lookup-name>
</resource-env-ref>
or if your resource-ref lacks lookup-name and you instead have a ibm-web-bnd.xml file with a binding-name,
<resource-ref name="java:comp/env/jms/topicRef" binding-name="jms/myTopic">
</resource-ref>
then specify jms/myTopic as the JNDI name of the Topic.
Application code will then be able to do:
Topic topic = InitialContext.doLookup("java:comp/env/jms/topicRef");
Some optimizations/special cases:
If you have neither lookup-name nor binding-name, then WebSphere Application Server computes a default binding via the resource reference name. If this is the case for your resource reference, then you will have a deployment descriptor such as the following without any bindings file,
<resource-ref>
<res-ref-name>jms/myTopicConnectionFactory</res-ref-name>
<res-type>javax.jms.TopicConnectionFactory</res-type>
</resource-ref>
In the above case, specify jms/myTopicConnectionFactory as the JNDI name.
The application will be able to look it up as,
TopicConnectionFactory tcf = InitialContext.doLookup("java:comp/env/jms/myTopicConnectionFactory");
I try to deploy a Java EE Application containing several EJB Timer Services (with persistence=true).
The server complains that no datasource was defined:
Caused by: javax.ejb.EJBException: See nested exception; nested exception is: java.lang.IllegalStateException: The ejbPersistentTimer feature is enabled, but the defaultEJBPersistentTimerExecutor persistent executor cannot be resolved. The most likely cause is that the DefaultDataSource datasource has not been configured. Persistent EJB timers require a datasource configuration for persistence.
The ejbPersistentTimer-3.2 feature is turned on.
I can not find an example how to configure such a datasource in the server.xml file
I tried:
<dataSource id="timerDataSource" jndiName="jdbc/timerDataSource">
</dataSource>
<databaseStore id="EJBTimerDatabaseStore"
tablePrefix="EJBTimer_" dataSourceRef="timerDataSource" />
<persistentExecutor
id="defaultEJBPersistentTimerExecutor"
taskStoreRef="EJBTimerDatabaseStore" />
But this seems to be not enoght? Did I need to activate DerbyDB as a feature too?
It looks like your <dataSource> configuration is missing a few items:
A <jdbcDriver> which points to the JDBC driver jar that corresponds with the DB you are using
A <properties> element which identifies DB properties such as the DB server's hostname, port, and DB name.
Since you mentioned using DerbyDB, here is an example of what Derby config might look like:
<dataSource id="timerDataSource" jndiName="jdbc/timerDataSource">
<jdbcDriver libraryRef="DerbyLib"/>
<properties.derby.embedded databaseName="${server.config.dir}/data/EJBTimerDB" createDatabase="create"/>
</dataSource>
<library id="DerbyLib">
<fileset dir="${server.config.dir}/derbyDriverDir/"/>
</library>
For additional info on configuring DataSources in Liberty, check out this doc:
Configuring relational database connectivity in Liberty
I am trying to get Spring working with tomcat JNDI resource to access my database. My project works if a META-INF/context.xml in my project with the resource information but once I remove it it stops.. why.
If you deploy a Web application in Tomcat, in the deployment process, Tomcat will copy the META-INF/context.xml file in $CATALINA_HOME/conf/ so the context will be available for your application. Take in mind, that if you remove context.xml from you application because you dont want it, you also have to delete it manually from $CATALINA_HOME/conf/
If you have edited the server.xml for including your dababase resource and is not working when you remove context.xml it could be because you made some mistake defining your resourde in server.xml
UPDATED:
When resource is in server.xml, in context you should make a reference to global resource in server.xml. For example:
<Context crossContext="true" reloadable="true" >
<ResourceLink name="jdbc/myApp" type="javax.sql.DataSource" global="jdbc/myApp" />
</Context>
This is unrelated to Spring.
To use JNDI you are expected to define the various resources either as global configuration or as application specifici configuration. For example JNDI DataSource Configuration
Why do you expect it to work in any other case? How would Tomcat know which resources to provide if you don't define them?
UPDATE:
You define a resouce in your server.xml but you have to associate the resource with your web application. That is why you also need to modify context.xml
The iBatis framework has been significantly tweaked between versions 2 & 3, so much that even the config file (now often referred to as MapperConfig.xml) is different.
That being said, there are lots of examples online on how to create a JDBC connection pool with iBatis, but I couldn't find one example on how to do it with JNDI. There is an updated user guide at: http://svn.apache.org/repos/asf/ibatis/java/ibatis-3/trunk/doc/en/iBATIS-3-User-Guide.pdf which does refer to the JNDI settings on page 19, but I still couldn't it get it correctly communicate with the database.
A working example of a JDNI (container managed connection pool) in iBatis 3 would be greatly appreciated!!
Assuming you've already got a JNDI database resource set up, the following environment for iBatis 3's configuration XML file works for me (running on Tomcat):
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="JNDI">
<property name="data_source" value="java:comp/env/jdbc/webDb"/>
</dataSource>
</environment>
This is what I have in my config file, works well in Glassfish and WebSphere:
<dataSource type="JNDI">
<property name ="data_source" value="jdbc/cpswebmon"/>
</dataSource>
"jdbc/cpswebmon" is the JNDI resource name on my application server