I am using Dropwizard with HikariCP connection pool, but I guess this could be about using any connection pool. How do I configure Dropwizard to call shutdown() method of HikariCP datasource whenever application shuts down? Is it even possible?
HikariCP FAQ states that Spring or other IOC containers make it possible, but I'm not using DI frameworks at this point, just Dropwizard.
Take a look at the Managed interface: http://www.dropwizard.io/manual/core.html#managed-objects
Related
I read from DBCP2 documentation that this new version supports JMX monitoring for connection pool, but I couldn't find any example which shows actual usage.
I have a simple JDBC based java application which uses dbcp2 to create a connection pool which is used by a simple query service, and I want to monitor these connection via another tool like VisualVM using JMX.
DBCP2's BasicDataSource has methods like setJmxName()
which I don't see any usage for that, and don't know how to use it.
If someone is not familiar with JDBC, you can read about it here.
Any help on this will be appreciated.
Thanks!
I haven't found any documentation either, but I have figured a few things out by digging through the source code.
You just need to create a BasicDataSource or BasicManagedDataSource object, like you normally would, and then call the setJmxName() method. The DataSource will then register itself with the platform's MBean server when you call the getConnection() method and unregister itself when you call the close() method.
Setting a JMX name of "org.apache.dbcp:DataSource=mydbname" works, an example Apache uses for unit tests can be found here.
Tomcat has a built-in JDBC connection pooling, but unfortunately no built-in JMS connection pooling.
We are migrating a legacy Tomcat web application from WebSphere MQ version 6 to 7.
Unfortunately, connection pooling has been removed in WebSphere MQ 7 as described here: http://www-01.ibm.com/support/docview.wss?uid=swg21665128
Now we are afraid that we will run into troubles if we just use the following code for configuring MQ in Tomcat:
<Resource name="jms/XXXQCF" auth="Container"
type="com.ibm.mq.jms.MQQueueConnectionFactory" factory="com.ibm.mq.jms.MQQueueConnectionFactoryFactory"
description="JMS Queue Connection Factory"
HOST="xxx.com" PORT="1429" CHAN="XXX" TRAN="1"
QMGR="XXX" />
The reason for our concerns is that this will not use a pooled JMS provider when using MQ 7. For details, see also http://activemq.apache.org/jmstemplate-gotchas.html
Alternative solutions we see are:
1) Use of Atomikos
Atomikos has a com.atomikos.jms.AtomikosConnectionFactoryBean that can be used instead of MQQueueConnectionFactory
But using an XA transaction manager is a huge overhead when we don't need XA
2) Use Spring's CachingConnectionFactory
looks like a good solution, but unfortunately our legacy application does not use Spring.
So we assume that using CachingConnectionFactory would mean quite some effort.
3) Use Apache Commons Pool
looks promising too, but implementing it correctly for JMS will require some good JMS knowledge
Our questions:
is there a JMS provider that can be used to wrap MQQueueConnectionFactory and that will pool connections, sessions, producers and consumers?
did anyone succeed in implementing one of the alternative solutions we outlined above?
As proposed by Umapathy in option 3, we now opted for the approach using Spring's CachingConnectionFactory, and it works well even for a non-Spring application. All you need to do is add the Spring Jars to the classpath, and wrap the MQQueueConnectionFactory with a CachingConnectionFactory.
We chose to create our own Tomcat QueueConnectionFactoryFactory that enables us to leave the original application code completely untouched, you just need to replace the original MQ connection factory from the Tomcat configuration file (shown above in the question) with the following XML definition:
<Resource name="jms/XXXQCF" auth="Container"
type="org.springframework.jms.connection.CachingConnectionFactory"
factory="at.rsf4j.core.utilities.RSFCachingMQQueueConnectionFactoryFactory"
description="JMS Queue Connection Factory"
HOST="xxx.com" PORT="1429" CHAN="XXX" TRAN="1"
QMGR="XXX" />
Here is the (simplified) code (without error checking) for the RSFCachingMQQueueConnectionFactoryFactory:
public class RSFCachingMQQueueConnectionFactoryFactory implements ObjectFactory{
public Object getObjectInstance (Object obj, Name name, Context nameCtx, Hashtable<?,?> environment)
throws NamingException {
Reference ref = (Reference) obj;
String beanClassName = ref.getClassName();
Class<?> beanClass = Class.forName(beanClassName);
if (CachingConnectionFactory.class.isAssignableFrom(beanClass)){
MQQueueConnectionFactoryFactory cff = new MQQueueConnectionFactoryFactory();
Reference mqReference = new Reference(
MQQueueConnectionFactory.class.getName());
Enumeration<RefAddr> allAddrs = ref.getAll();
while (allAddrs.hasMoreElements()){
mqReference.add(allAddrs.nextElement());
}
MQQueueConnectionFactory cf = (MQQueueConnectionFactory)cff.getObjectInstance(mqReference, name, nameCtx, environment);
CachingConnectionFactory ccf = (CachingConnectionFactory)beanClass.newInstance();
ccf.setTargetConnectionFactory(cf);
return ccf;
}
}
I think you already know the answer.
option 1: Go with a Java EE application server. This has inbuilt JMS pools.
option 2: If this is a simple application that does a single job (like putting on a queue with fire and forget type), you can connect to the JMS provider (qmgr) and create the producer or consumer in the servlet_init method. This means the legacy code needs an update. You also need to take care of the reconnect when something breaks as JMS reconnect properties doesn't kick off a reconnection (as far as my experience goes).
option 3: I have gone with Spring's CachingConnectionFactory when the application happens to be more than a little complex than one in option 2. I have applications that use JMSTemplate and some doesn't.
What is the difference between Spring DriverManagerDataSource and apache BasicDataSource?
Which of them is preferable and in which situations?
Thank you.
As per the Spring documentation
This class is not an actual connection pool; it does not actually pool Connections. It just serves as simple replacement for a full-blown connection pool, implementing the same standard interface, but creating new Connections on every call.
If you need a "real" connection pool outside of a J2EE container, consider Apache's Jakarta Commons DBCP or C3P0. Commons DBCP's BasicDataSource and C3P0's ComboPooledDataSource are full connection pool beans, supporting the same basic properties as this class plus specific settings (such as minimal/maximal pool size etc).
Also read Controlling database connections
When using Spring's JDBC layer, you obtain a data source from JNDI or you configure your own with a connection pool implementation provided by a third party. Popular implementations are Apache Jakarta Commons DBCP and C3P0. Implementations in the Spring distribution are meant only for testing purposes and do not provide pooling.
From Spring DriverManagerDataSource API:
This class is not an actual connection pool; it does not actually
pool Connections. It just serves as simple replacement for a full-blown
connection pool, implementing the same standard interface, but creating new
Connections on every call.
In other words, it may be OK for tests but in real application use Apache DBCP
I am creating a JDBC connection pool resource for GlassFish, using the server's Admin Console.
One of the fields on the page to create the pool is labeled 'Resource Type'. This field has four possible values: javax.sql.DataSource, javax.sql.XADataSource, javax.sql.ConnectionPoolDataSource and javax.sql.Driver, but the help text for the Create JDBC connection pool 'wizard' does not have much info about the advantages and disadvantages of these choices.
When prompted to pick a resource type which should I choose?
I am going to connect to a local MySQL server. It would be nice to get an explanation of the differences between the choices in the drop-down as well.
Below are the scenarios where you would need each of the resource types listed. Hope this helps.
DataSource
DataSource A DataSource object is a factory for Connection objects. When using simple DataSource, appserver uses its own pooling instead of native.
ConnectionPoolDataSource
A ConnectionPoolDataSource object is a factory for PooledConnection objects. ConnectionPoolDataSource is used to give access to PooledConnection which implements native pooling by JDBC driver. In this case application server can implement connections pooling using this native interface. Please refer to Java API to know what a PooledConnection is...A ConnectionPoolDataSource can use a third party implementation for pooling - as far as I know for Tomcat, for instance, DBCP connection pooling is used.
XADataSource
You need an XADataSource if you want to execute a Distributed Transaction. You should use XADataSource instead of DataSource if the application
Uses the Java Transaction API (JTA)
Includes multiple database updates within a single transaction
Accesses multiple resources, such as a database and the Java Messaging Service (JMS), during a transaction
I've been looking at a number of JDBC connection pools, but I have the specific requirement that the pool needs to be JTA aware, which leaves me with a short list of Apache DBCP and OW2 XAPool. The other pools I looked (c3p0, Proxool, BoneCP) at did not appear to satisfy the JTA requirement.
Does anyone have a recommendation about either XAPool, DBCP, or a connection pool I have not mentioned here?
Some standalone transaction managers like Atomikos or Bitronix have their own integrated connection pool. Such a pool is JTA compliant and would solve your problem.
Recently I was facing the same problem and finally I ended up with Bitronix and its integrated connection pool. It works well.
If timelines permit and there's this requirement, I can add JTA support to BoneCP if you want.
Wallace
(BoneCP author)