Spring application should start even database is not available at startup - spring

I have an old spring application which uses jee:jndi-lookup for datasource. This application running on Tomcat 8.
<jee:jndi-lookup id="datasource" jndi-name="java:/comp/env/jdbc/Tomcat8Database" destroy-method="close" expected-type="javax.sql.DataSource" lookup-on-startup="false"/>
The database may be sometime down at startup of the application, but as I also tried to lazy-init spring beans it did not helped as what it seems like that JNDI lookup in spring happened on Startup always or its not in spring controls as Server provide Pooling over connections.
Any idea or code example will be helpful.

According to spring javadoc, For a lazy lookup, a proxy interface needs to be specified.
Proxy interface specify the proxy interface to use for the JNDI object.
Typically used in conjunction with "lookupOnStartup"=false and/or "cache"=false. Needs to be specified because the actual JNDI object type is not known in advance in case of a lazy lookup.
Try:
<jee:jndi-lookup id="datasource" jndi-name="java:/comp/env/jdbc/Tomcat8Database" destroy-method="close" expected-type="javax.sql.DataSource" lookup-on-startup="false" proxy-interface="javax.sql.DataSource"/>

Related

ActiveMQ in JBoss - Using JNDI for jdbcPersistentAdaptetr

Running ActiveMQ in clustered environment with a Master/Slave relationship using Oracle as a datastore. Using a jdbcPersistentAdapter.
<jdbcPersistenceAdapter dataSource="#dataSource" createTablesOnStartup="false" lockKeepAlivePeriod="30000"/>
The activemq broker is running embedded in JBoss.
I would like to replace the dataSource bean (contains credentials and url string) with a JNDI reference since that already manages the database connection. Is this possible?
Load the dataSourcebean from JNDI instead. Something like this should work (using a correct JNDI name from your setup).
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/MyDatabase"/>
</bean>

Unit Testing based on JNDI , ejb and spring

In my application I am injecting some of services based on EJB with use of Spring IOC through JndiObjectFactoryBean like below mentioned so during run the junit I am getting this exception "java.lang.IllegalArgumentException: This JNDI operation is not implemented by the JNDI provider."
Could some please let me know how I'll configure for Junit.
<bean id="xxxMenuItemService" class="xxxMenuItemServiceyyy">
<property name="xxxMenuItemDelegator" ref="xxxMenuItemDelegator" />
</bean>
<bean id="approveMenuItemServiceRemote"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName"
value="ejb/XXXXXXXX" />
have a look at the SimpleNamingContextBuilder from org.springframework.mock as it provides a full context builder where you can bind mock or other objects for use by Spring's JNDI lookup.
One thing to do though is to make sure you build the SimpleNamingContextBuilder in the static #BeforeClass of JUnit 4. this means that it is all initialized and waiting before the Spring Application Context is started and you won't have any JNDI lookup failures.

Spring JNDI Configuration

We are using Spring to do JNDI look-up for our data access requirements. We are making calls to multiple stored procedures (in Sybase). I wanted a way to control the auto-commit property of the transactions while calling these stored procs. I was able to achieve it with BasicDataSource (property name="defaultAutoCommit").
But I got stuck when we moved to doing JNDI look-up (from Weblogic).
<jee:jndi-lookup jndi-name="WL_data_source" id="dataSource" />
<bean id="procedureHandlerBean" class="myclass">
<property name="procDataSource" ref="dataSource"/>
</bean>
After researching for a few days, it appears to me that I can use JtaTransactionManager. However, I am not sure if I can use the transaction manager to configure auto-commit on a per procedure call basis (due to different chained/unchained mode requirements of different procs). Is there a clean way to achieve this? Thanks

Can't seem to get a JNDI JDBC resource working in Liferay

No joy in the Liferay forum on this issue and the clock is ticking on this project. This may be caused by my lack of knowledge of Spring.
I have a JNDI global resource defined in server.xml and a resource link in context.xml in my Tomcat 7 /conf folder. I KNOW the JNDI resource is being loaded because I see the validation query being run as the server starts up. So far so good.
I have a portlet that just provides services to other portlets. In that portlet I have a hibernate.cfg.xml which has a session-factory that also points to the JDBC resource (don't know if this is needed or not). I also have an ext-spring.xml file in the services portlet that has the following:
<bean id="liferayHibernateSessionFactory" class="com.liferay.portal.spring.hibernate.PortletHibernateConfiguration" >
<property name="dataSource" ref="MyJDBCResource" />
</bean>
<bean id="MyJDBCResource" class="org.springframework.jndi.JndiObjectFactoryBean" >
<property name="jndiName" value="java:comp/env/jdbc/MyJDBCResource" />
</bean>
Adding the above in ext-spring.xml fixed an issue with a bean error on that services portlet upon deployment. In that service builder built portlet, a services jar was created and I put that service jar in the Tomcat_Home/lib/ext folder so that I could use the services provided by the portlet in my portlet. So far so good. But, when I invoke the portlet method which calls the services provided by the other portlet with the JNDI references, I get a "user lacks privilege or object not found" error. It is definitely object not found. When the query is run I see absolutely NO activity on the JDBC connection specified by the JNDI resource entry and in drilling down on the connection properties I only see the HSQLDB driver in use. It should be using the MSSQL driver specified in my global resource JNDI entry as far as I understand it.
SO WHAT AM I DOING WRONG? Do I need to add some configuration entries in the portlet that invokes the services?
This seems so simple. In reading the many posts that give instructions on using JNDI/JDBC resources I seem to have followed them correctly. Is there some trick to using JNDI/JDBC resources in LR 6.1.1 and Tomcat 7 that I have missed?
Thanks (and really hoping for some answers!).
First, you could try rewrite JNDI resource reference like this:
<bean id="MyJDBCResource" class="org.springframework.jndi.JndiObjectFactoryBean" >
<property name="jndiName" value="jdbc/MyJDBCResource" />
</bean>
also, you could try different approach on JNDI resource lookup in Spring:
<jee:jndi-lookup id="MyJDBCResource" jndi-name="jdbc/MyJDBCResource" expected-type="javax.sql.DataSource" />
Not sure about first approch, but second will definitively fail early in case no JNDI resource could be found.
Hope this helps.

Spring JTA transaction with JPA and jndi datasource for Websphere

I am having multiple datasource and one one database configured with JPA. I am using websphere 7. I want all these datasouces to be configured as global transactions. I am using below spring configurations but the transactions are not working as expected global transaction. If one db is failing then the other db is getting commited which is not expected as single global transactions. Can you please help me where i m doing incorrect,
I am having 2 datasouce one as configured below with id="us_icfs_datasource" and another using JPA
<jee:jndi-lookup id="entityManagerFactory" jndi-name="persistence/persistenceUnit"/>
<bean id="pabpp" class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" />
<!-- Needed for #Transactional annotation -->
<tx:annotation-driven/>
<jee:jndi-lookup id="US_ICFS_DATASORCE"
jndi-name="jdbc/financing_tools_docgen_txtmgr"
cache="true"
resource-ref="true"
proxy-interface="javax.sql.DataSource" />
also I have added below code in web.xml
<persistence-unit-ref>
<persistence-unit-ref-name>persistence/persistenceUnit</persistence-unit-ref-name>
<persistence-unit-name>persistenceUnit</persistence-unit-name>
</persistence-unit-ref>
<persistence-context-ref>
<persistence-context-ref-name>persistence/persistenceUnit</persistence-context-ref-name>
<persistence-unit-name>persistenceUnit</persistence-unit-name>
</persistence-context-ref>
below is my code where i m using transaction
> #Transactional public TemplateMapping addTemplateMapping(User user,
> TemplateMapping templateMapping) throws
> TemplateMappingServiceException { .... }
On Websphere you should use this bean to hook into the Websphere transaction manager:
<bean id="transactionManager"
class="org.springframework.transaction.jta.WebSphereUowTransactionManager"/>
See also this article
EDIT:
In order to use 2-phase commit (i.e. ensuring consistency across multiple resources), you will need to use XA data sources. See this article for details.
First of all your data sources that participate in global transaction must be of javax.sql.XADataSource type.
You also have to set transaction type in your persistence unit to JTA (not RESOURCE_LOCAL).
And you need to inform your JPA implementation that you want to do global transactions.

Resources