JBoss 6 : Retrieve list of configured datasources at runtime

Introduction

Working with database connections on enterprise application servers like JBoss is in 99.9% very simple and well standardized. What one needs to do is:

  1. Configure datasources (*-DS.xml files)
  2. Configure persistence units in persistence.xml file
  3. Use dependency injection (@PersistenceContext(unitName=”pUnit”)) in order to obtain EntityManager

, and voilà: you are ready to work with defined databases. In your code you do not need to create any database connections or bother what is the name of database, username/password as well as datasource name. However, there is this 0.1% of cases in which your application is  extraordinary (been there 😉 ) and you need to have some more information and control over db-layers or you just simply need it for some reason I cannot even imagine 🙂 If you do, in this post you will find how to retrieve a list of available datasources.

I assume you already know

JBoss6, JMX basics, Datasource configuration on JBoss 6,  JEE concepts.

I am working with:

JBoss-6.1.0.Final, using Windows 8

State of application

Lets assume we have 2 datasources configured : DefaultDs and PostgresXADS.

admin_console_ds_lists

Jboss Admin Console – Available Datasources

JMX-Console-eye view

In order to programatically retrieve information about those datasources we will use JMX MBeans of type WrapperDataSourceService which are holding all information we need at that point. Basically we will do simple lookup, which you can also obtain using JBoss JMX Console. We will use JMX Name :

jboss.jca:service=DataSourceBinding,*

If you have your JBoss running please type into browser: http://localhost:8080/jmx-console/HtmlAdaptor?action=displayMBeans&filter=jboss.jca:service=DataSourceBinding. Depending on your JBoss datasources configuration, you should see something like :

JMX Console : List of DataSourceBinding mbeans

JMX Console : List of DataSourceBinding mbeans

If you click on any link from above list, you will be presented with more detailed information about MBean. For instance it can look like:

JMX Console: DatasourceBinding MBean View

JMX Console: DatasourceBinding MBean View

In the above figure you can see some of the attributes of chosen MBean. What is interesting for us is BindName, which states for JNDI address under which PostgresXADS datasource is stored.  Having it, we can easily lookup the Datasource instance from JNDI Context. Now the question: how to write Java code which does the same?

Code point of view

Simple code snippet which presents how to list Datasources. I am running this code in managed EJB Stateless Bean.

List avaliableDatasources = new ArrayList<DataSource>(); 
// Get the starting point into the namespace
Context ctx = new InitialContext();

// retrieve MBean server
MBeanServer server = java.lang.management.ManagementFactory.getPlatformMBeanServer();

// create proper jmx name, (1)
final ObjectName filterName = new ObjectName("jboss.jca:service=DataSourceBinding,*");

// get the results matching given filter. (2)
final Set<ObjectInstance> mBeans = server.queryMBeans(filterName, null);

// iterate over mbeans and retrieve information about bind name
// (jndi name) of datasource
for (final ObjectInstance mBean : mBeans) {

 // simple check which guarantees that we are reading only real
 // datasources (not aliases) (3)
 if (isNotAlias(mBean)) {

  // get name for mbean describing current datasource
  final ObjectName dsBindingMBeanName = mbean.getObjectName();

  // one of the attributes of DataSourceBinding bean is
  // "bindname" , we will read that attribute now: (4) 
  String bindName = (String) server.getAttribute(dsBindingMBeanName, "BindName");

  // having the jndi name, we can look up the datasource instance (5) 
  final javax.sql.DataSource ds = (javax.sql.DataSource) ctx.lookup(bindName);

  avaliableDatasources.add(ds);
 }
}
//////////////////////
 
private boolean isNotAlias(ObjectInstance mBean) {
 
  String ALIAS_SERVICE_CLASS_NAME = "org.jboss.services.binding.AliasJndiService";
  boolean isNotAliasDS = !ALIAS_SERVICE_CLASS_NAME.equals(mBean.getClassName()); 
  return isNotAliasDS;  
}  

Some more detailed explanation to the code:

1) We are creating object which represents JMX Name “jboss.jca:service=DataSourceBinding,*” (read more: http://www.oracle.com/technetwork/java/javase/tech/best-practices-jsp-136021.html). This is the same name we can use in JMX-Console in order to retrieve mbeans.

2) We are getting all mbeans which are listed under given JMX filter name. We should get the same list which we have obtained before in the JMX-Console : see

3) Given list of MBeans contains not only our 2 datasources but also one alias : jboss/datasources/ExampleDS. It links to DefaultDS and is not binded in the JNDI, therefore we do not want it on our list. That is why, we are filtering out this alias by simple check of MBean className.

4) Having the exact JMX name of an MBean, we can get any of its attributes or even call any of its public methods. In this case we just need to read out the “BindName” attribute. (see the list of attributes here: list)
5) Having the BindName of Datasource, we are  actually having its JNDI address under which given  Datasource is stored in application context.

Summary

Presented code is very simple and may not need so much of explanation, but I think it is good to know how it works in the background and also how to check the results on JMX Console which can spare some time and avoid unexpected results.

If you are going to migrate to JBoss 7 soon, you must take a note that it will not work there, since the whole server configuration is different and also provided Management Beans are different. If you would like to see how to do the same operation on JBoss 7,  you can read it in my other blog post which will come out this month.

Links which explain more about mentioned topics:

JMX Console : https://community.jboss.org/wiki/JMXConsole

Configuring Datasources on JBoss: http://docs.jboss.org/jbossas/docs/Getting_Started_Guide/4/html/Using_other_Databases-DataSource_Configuration_Files.html

JMX best practices: http://www.oracle.com/technetwork/java/javase/tech/best-practices-jsp-136021.html

JMX documentation: http://www.oracle.com/technetwork/java/javase/tech/docs-jsp-135989.html

Some words about MBeans on JBoss: http://docs.jboss.org/jbossas/docs/Server_Configuration_Guide/4/html/Using_JMX_as_a_Microkernel-JBoss_MBean_Services.html

Advertisements

One Response to JBoss 6 : Retrieve list of configured datasources at runtime

  1. Pingback: JBoss 7: Retrieve list of configured datasources at runtime | My Fascinations

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: