Announcement Announcement Module
Collapse
No announcement yet.
JEE6: <jee:jndi-lookup> can't find resource-ref but @Resource can Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • JEE6: <jee:jndi-lookup> can't find resource-ref but @Resource can

    This is a bit puzzling to me. Please help out if you can.

    I have an EAR with one JAR module. Inside the JAR, I have a timer bean that has a JDBC @Resource injected. Simple example:
    Code:
    @Singleton
    @Startup
    public MyTimerBean {
        @Resource(name="jdbc/ds")
        private DataSource ds;
    
        @Schedule(second = "0", minute = "*", hour = "*", persistent = false)
        public void execute() { 
            System.out.println(ds);
        }
    }
    The JDBC resource is defined at the EAR level. I am using JEE 6 so this possible. I have it defined at the EAR/application level because I plan on reusing it across several other beans.
    HTML Code:
    <application ...>
      <module>
        <ejb>my-ejb.jar</ejb>
      </module>
      <resource-ref>
        <res-ref-name>jdbc/ds</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <mapped-name>jdbc/serverds</mapped-name>
      </resource-ref>
    </application>
    This all works great. It works....
    But if I replace @Resource with a Spring lookup, Spring can't find it!
    Code:
    @Singleton
    @Startup
    @Interceptors(SpringBeanAutowiringInterceptor.class)
    public MyTimerBean {
    
        // spring config: <jee:jndi-lookup jndi-name="jdbc/ds" expected-type="javax.sql.DataSource" />
        @Autowired
        private DataSource ds;
    
        @Schedule(second = "0", minute = "*", hour = "*", persistent = false)
        public void execute() { 
            System.out.println(ds);
        }
    }
    From my glassfish server:
    Code:
    Caused by: javax.naming.NameNotFoundException: ds not found
    	at com.sun.enterprise.naming.impl.TransientContext.doLookup(TransientContext.java:248)
    	at com.sun.enterprise.naming.impl.TransientContext.lookup(TransientContext.java:215)
    	at com.sun.enterprise.naming.impl.TransientContext.lookup(TransientContext.java:219)
    	at com.sun.enterprise.naming.impl.SerialContextProviderImpl.lookup(SerialContextProviderImpl.java:77)
    	at com.sun.enterprise.naming.impl.LocalSerialContextProviderImpl.lookup(LocalSerialContextProviderImpl.java:119)
    	at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:505)

  • #2
    Solution

    I don't know if this is a limitation of Spring or a limitation of Glassfish JNDI lookup, but obviously Spring works differently than @Resource.

    The answer is for application.xml to define the <resource-ref> using the java:app/env namespace and refer to that namespace explicitly by Spring.

    Code:
    <application ...>
      <module>
        <ejb>my-ejb.jar</ejb>
      </module>
      <resource-ref>
        <res-ref-name>java:/app/env/jdbc/ds</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <mapped-name>jdbc/serverds</mapped-name>
      </resource-ref>
    </application>
    Spring config:
    Code:
    <jee:jndi-lookup jndi-name="java:/app/env/jdbc/ds" expected-type="javax.sql.DataSource" />

    Comment

    Working...
    X