During JBoss startup I have a Persistence Manager that depends on a JDBC connection (DefaultDS). The JDBC connection starts fine whether or not it can actually connect to the database so when the Persistence Manager starts it thinks it has a connection. Then it blows up because it cannot connect to the database and never starts. This prevents my DestinationManager from starting and causes all kinds of headache.
Is there a way to make MBeans that depend on the JDBC connection not start unless the JDBC connection can actually connect to the database? As an alternative, is there a way to make the JDBC connection depend on an MBean that is only active while the database can be connected to?
tl;dr; All I need is for my MBeans/DestinationManager to wait until the database (DefaultDS) is available before booting.
Please comment if you need more info about the enviornment.
JBoss version 4.2.3
Database: MsSql
If I understand the issue correctly, you're having a problem because even though the DefaultDS data source reports that it has started, since it has not acquired any connections, you don't necessarily know that connections can be made .
Unfortunately, even with the prefill option enabled, the datasource service will still start normally even if it cannot make a connection.
Your best bet is to implement a ServiceMBean that checks an actual connection from the datasource before it reports being started. For this example, we'll call it org.bob.ConnChecker and will deployed using the ObjectName org.bob:service=ConnChecker.
Your deployment descriptor should look something like this:
<mbean code="org.bob.ConnChecker" name="jboss.mq:service=DestinationManager">
<depends optional-attribute-name="DataSource">jboss.jca:name=DefaultDS,service=ManagedConnectionPool</depends>
</mbean>
So your service will not be started until the data source has started. Your service will not start unless it can get a connection. Now you just have to add org.bob:service=ConnChecker as a dependency of the DestinationManager:
jboss.mq:service=MessageCache jboss.mq:service=PersistenceManager jboss.mq:service=StateManager jboss.mq:service=ThreadPool jboss:service=Naming org.bob:service=ConnChecker
The code for ConnChecker will look something like this:
....
import org.jboss.system.ServiceMBeanSupport;
....
public class ConnChecker extends ServiceMBeanSupport implements ConnCheckerMBean {
/** The ObjectName of the data source */
protected ObjectName dataSourceObjectName = null;
/** The Datasource reference */
protected DataSource dataSource = null;
/**
* Called by JBoss when the dataSource has started
* @throws Exception This will happen if the dataSource cannot provide a connection
* @see org.jboss.system.ServiceMBeanSupport#startService()
*/
public void startService() throws Exception {
Connection conn = null;
try {
// Get the JNDI name from the DataSource Pool MBean
String jndiName = (String)server.getAttribute(dataSourceObjectName, "PoolJndiName");
// Get a ref to the DataSource from JNDI
lookupDataSource(jndiName);
// Try getting a connection
conn = dataSource.getConnection();
// If we get here, we successfully got a connection and this service will report being Started
} finally {
if(conn!=null) try { conn.close(); } catch (Exception e) {}
}
}
/**
* Configures the service's DataSource ObjectName
* @param dataSourceObjectName The ObjectName of the connection pool
*/
public void setDataSource(ObjectName dataSourceObjectName) {
this.dataSourceObjectName = dataSourceObjectName;
}
/**
* Acquires a reference to the data source from JNDI
* @param jndiName The JNDI binding name of the data source
* @throws NamingException
*/
protected void lookupDataSource(String jndiName) throws NamingException {
dataSource = (DataSource)new InitialContext().lookup(jndiName);
}
}
The code for ConnCheckerMBean looks like this:
....
import org.jboss.system.ServiceMBeanSupport;
....
public interface ConnCheckerMBean extends ServiceMBean {
public void setDataSource(ObjectName dataSourceObjectName);
}
So you will still get errors if connections cannot be made to the database, but the DestinationManager will not start, and hopefully that will be better than the headaches you're having now.