How to access EJB bean through context lookup from ServletContextListener - spring

Need to call a EJB service from the servlet context listener's contextInitialized() method. Application is running on JBOSS, though the context listener works fine, I'm not able to access the EJB bean through JNDI look up.
Because the web deployment in JBOSS happens before EJB beans are bound with JNDI tree. How to overcome from this? Is there a way to configure JNDI bind early or start the web deployment later once EJB's are completely deployed?
I had put Thread.sleep() before the service call in the contextInitialized() method, it is working fine in my JBoss5.1.0 GA, and the same did not work in other machines JBoss of same version.
Applications needs this because, we want to load some master data from the DB and make it available in the web layer (kind of caching). Does JBOSS startupmbean suit this requirement? If yes how can I make the data available to web layer?
Also if any alternative ways are available, please suggest.

Poll for the EJBs in contextInitialized(). So instead of just sleeping for a certain time, try to connect to the EJB. If that fails, sleep, and retry, until the EJBs are available. In this case the context initialization is blocked.
Implement the cache as a lazy one: Fill the cache during the first query (and use the same polling procedure: connect to the EJB, retry until it becomes available). In this case the cache blocks.
You could split your deployment into two parts: One for the EJBs, one for the web application. Then deploy the first, and delay deployment of the web application until the EJBs are bound (either by watching the log file or by trying bind to the EJB from a command line app)

Related

Transaction management in Spring: Does support come from Spring or container?

I am trying to understand the transaction management in Spring, and I have got some doubts.
I read a bit about transaction management in EJB world, which can be CMT or BMT. For CMT, as per the documentation, it is Application server (e.g. JBOSS) which manages the transaction.
Now, coming to Spring transaction management, and considering using Web container only (Apache Tomcat), how does this work?
Does Spring have its own transaction management with capability of handling local transaction and global transaction (which works with 2 phase commit). Do the actual support need to come by the underlying container (in this case Apache tomcat) or support from framework is sufficient?
I am not clear how all these pieces fit together.
Can anyone help me understand this?
Spring doesn't include any kind of transaction capability of its own, it only provides ways to connect to transaction functionality provided by the container or by standalone libraries.
If you run your application on Tomcat and don't provide any transaction manager libraries like bitronix, then you get only local jdbc transactions provided by the servlet container.
When you read the bullet points at https://docs.spring.io/spring/docs/4.2.x/spring-framework-reference/html/transaction.html notice it says spring is providing abstractions, that means it is providing access through its own apis and using aop to make transactions nonintrusive, but not providing any implementation of transactional functionality. It's facilitating gluing things together, which is the main thing spring does.

How to make spring servlet load-on-startup wait after tomcat jndi (global resources) are loaded

I have a Spring servlet called with load-on-startup = 1 and it requires a database connection, but sometimes, connection is null and the appLoader servlet fails. The connection is null because tomcat didn't had the time to load the global resources properly.
Question : How do I ask Spring to wait for jndi proper loading? I mean, order it in some way.
Dirty solution : Make another servlet with active wait and waiting for a working connection before calling my appLoader...
1) The job of <load-on-startup> is to start a servlet at the time of deployment. It just initiates(starts) the process after that it has no control over that servlet.
The entire control of the started servlet is in the hands of the web container.
The behaviour of the web container can be programmatically controlled using Event Handling mechanism.
2) Events are basically occurrence of something. Changing the state of an object is known as an event.
2.1) You can handle the events of web container using event listeners of servlet and perform some important tasks such as creating tables of the database, creating database connection object etc. at time of deploying the project.
There are many Event classes and Listener interfaces in the javax.servlet and javax.servlet.http package.
You can use ServletContextListener to store the connection object in the context attribute and later fetch that connection object from servlet context.
Here are few examples where database connection object is stored in servlet context. example1 example2 example3
2.2) You can use Event Handling mechanism of spring framework.
In spring you can poll your database connection using ContextStartedEvent that is raised when an ApplicationContext gets started.
Here, are some spring events with example.

How to define a JNDI Datasource on Undertow?

I have a running Spring application that already works on Weblogic and JBoss, and I'm adding the option to run it by itself with Spring Boot.
As it has a Java EE architecture, it has a container-managed datasource that is looked up by a JNDI name, and I wanted to keep it that way.
I see that Spring Boot has the ability to use a EE container called Undertow, that it turns out to be the Wildfly EE engine.
I've done A LOT of research on how to define this JNDI Datasource in Undertow with config files and stuff, but I can't find any documentation on that on Undertow's website and neither on WildFly documentation.
Has someone already done that? I need to know how to define this Datasource with a config file or something.
I don't think Undertow supports that - it's just a web server, nothing else, and very far from being a JEE container. Wildfly, on the other hand, is a JEE container and it uses Undertow as a web engine and builds up other JEE stuff around it.
Here's a quote from Undertow's official documentation:
On thing that makes Undertow unique is that it has no concept of a global container. Instead an Undertow server is assembled by the embedding application. This makes Undertow extremely flexible, and the embedding application can basically just pick the parts that they need, and assemble them in whatever way makes sense.
An Undertow server is basically composed of three things, one (or more) XNIO worker instance, one or more connectors, and a handler chain to handle incoming requests.

How should database connection failure be handled in OSGI?

If I expose DataSource as a service in OSGI, how should I handle database connection failure? Should I configure an interceptor of the DataSource service, which would catch database connection failure exception and unregister the DataSource service? Or would OSGI container handle the exception for me?
How should I configure the consuming service, so that it would be able to survive unavailability of the DataSource service, and allow user to re-try the transaction again?
You should handle unexpected exceptions in the same way as you do when you do not use OSGi.
You should use connection-pool and register that as an OSGi service. It will handle connection failures for you. You must always close the connection, even if there is an exception during using that connection. (in finally block before java 6 and by using a try-with-resources block after java 7). Connection pools provide their functionality by implementing DataSource interface.
There are many connection-pools. You can google for them.
I implemented two OSGi components based on commons-dbcp. One for pooling regular DataSources and one for pooling XADataSources. The component picks up the original DataSource/XADataSource OSGi service, than registers a new pooled-DataSource OSGi service.
You can find the source of the module here: https://github.com/everit-org/commons-dbcp-component
It is available at maven-central here: http://search.maven.org/#artifactdetails%7Corg.everit.osgi%7Corg.everit.osgi.jdbc.commons.dbcp%7C2.0.1%7Cbundle
After dropping the jar into your OSGi container, you will see the configuration possibilities of the components at the Configuration page of WebConsole (if you have webconsole).

How spring knows to refresh itis initial context if one cluster member goes down

I am using spring portlet mvc as my front end and connecting to some remote EJB running on a WAS. Now in my configuration file for the portlet where I specify the remote EJB lookup url, I have specified the url(s) as a cluster since the EJB is deployed in a clustered WAS. So the url looks like :iiop://server1:port,iiop://server2:port.
Now to save resources, spring mvc caches the initial context.Now I am noticing that spring is always able to make a connection to the remote ejb so long as one of the servers is up.
This is confusing to me since the cluster is resolved(for lack of a better word) at the time of lookup of the initial context and after that if the cluster member goes down, there should be a connection exception. So how does spring know when it should automatically refresh its initial context because the old context has become stale?
I found that in the applicationContext.xml file, there is the declaration:
<jee:remote-slsb id="remoteService" jndi-name="com.business.ejb.ServiceSLRemote" business-interface="com.business.ejb.ServiceSLRemote" cache-home="true" lookup-home-on-startup="false" resource-ref="false" refresh-home-on-connect-failure="true">
<jee:environment>
java.naming.factory.initial=${JAVA.NAMING.FACTORY.INITIAL}
java.naming.provider.url=${JAVA.NAMING.PROVIDER.URL}
</jee:environment>
</jee:remote-slsb>
It is the refresh-home-on-connect-failure="true" that tells the spring container that if the initial context has become stale, then it should refresh the connection. That is how it can work so long as one cluster member is active.

Resources