Spring Application starting before its Datasource and Messaging dependencies in JBoss EAP 8 / 7 /6 results in NameNotFoundException

Solution Verified - Updated

Environment

Red Hat JBoss Enterprise Application Platform (EAP)

  • 8.x
  • 7.x
  • 6.x

Issue

  • Our Spring Application is starting in parallel with some of the subsystems that the application has dependencies on. These subsystems are Messaging/HornetQ and the Datasource. When HornetQ and the Datasource start they register objects in JNDI for the destinations and the datasource we've defined. These destinations and datasource objects are required by our spring application to be available when it starts. In the logs, we can see that the JNDI names that the application fails to find are being registered after the application fails to load. How can we control the order of deployment for our application?
Caused by: javax.naming.NameNotFoundException: ConnectionFactory -- service jboss.naming.context.java.ConnectionFactory
        at org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:103)
        at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:197)
        at org.jboss.as.naming.InitialContext.lookup(InitialContext.java:120)
        at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:183)
        at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:179)
        at javax.naming.InitialContext.lookup(Unknown Source) [rt.jar:1.7.0_79]
        at org.springframework.jndi.JndiTemplate$1.doInContext(JndiTemplate.java:154) [spring-context-3.2.6.RELEASE.jar:3.2.6.RELEASE]
        at org.springframework.jndi.JndiTemplate.execute(JndiTemplate.java:87) [spring-context-3.2.6.RELEASE.jar:3.2.6.RELEASE]
        at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:152) [spring-context-3.2.6.RELEASE.jar:3.2.6.RELEASE]
        at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:178) [spring-context-3.2.6.RELEASE.jar:3.2.6.RELEASE]
        at org.springframework.jndi.JndiLocatorSupport.lookup(JndiLocatorSupport.java:95) [spring-context-3.2.6.RELEASE.jar:3.2.6.RELEASE]
        at org.springframework.jndi.JndiObjectLocator.lookup(JndiObjectLocator.java:105) [spring-context-3.2.6.RELEASE.jar:3.2.6.RELEASE]
        at org.springframework.jndi.JndiObjectTargetSource.getTarget(JndiObjectTargetSource.java:132) [spring-context-3.2.6.RELEASE.jar:3.2.6.RELEASE]
        ... 29 more
  • During server startup camel component fails to connect to messaging subsystem hornetq with exception javax.naming.NameNotFoundException

Resolution

List the datasource and messaging resources as resource-refs in the web.xml of the spring app:

<?xml version='1.0' encoding='UTF-8'?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">

<!-- Example of JMS ConnectionFactory Reference -->
  <resource-ref id="connectionFactory">
         <res-ref-name>connectionFactory</res-ref-name>
         <res-type>javax.jms.ConnectionFactory</res-type>
         <res-auth>Container</res-auth>
         <lookup-name>java:/ConnectionFactory</lookup-name>
  </resource-ref>

  <!-- Example of JMS Destination Resource Reference -->
  <resource-ref id="testQueue">
         <res-ref-name>testQueue</res-ref-name>
         <res-type>javax.jms.Queue</res-type>
         <res-auth>Container</res-auth>
         <lookup-name>java:/jms/queue/test</lookup-name>
  </resource-ref>

  <!-- Example of Datasource Resource Reference -->
  <resource-ref>
    <description>SQL server</description>
    <res-ref-name>myDatasource</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
    <lookup-name>java:jboss/datasources/ExampleDS</lookup-name>
  </resource-ref>
</web-app>

If the application is an ear, resource-refs can be configured in the ear's META-INF/application.xml for example:

 <?xml version="1.0" encoding="UTF-8"?>
 <application xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_6.xsd" version="6">
  <resource-ref>
    <description>SQL server</description>
    <res-ref-name>myDatasource</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
    <lookup-name>java:jboss/datasources/ExampleDS</lookup-name>
  </resource-ref>
 </application>

Related Solutions

[1] How to declare service lifecycle dependencies (such as EJB) between deployments in JBoss EAP 6

[2] JavaEE Environment Naming Context (ENC)

Components
Category

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.