8

I'm having trouble with a field annotated as @Resource in a Spring bean. What I have:

A field, with setter method, annotated @Resource

@Resource
private URL someUrl;

public void setSomeUrl(URL someUrl) {
    this.someUrl = someUrl;
}

An <env-entry> tag in my deployment descriptor (web.xml)

<env-entry>
    <env-entry-name>someUrl</env-entry-name>
    <env-entry-type>java.net.URL</env-entry-type>
    <env-entry-value>http://somedomain.net/some/path</env-entry-value>
</env-entry>

The application fails to start with a BeanCreationException, which I dont' expect because I don't necessarily want spring to inject a Spring-managed bean. I want Spring to process @Resource and retrieve the JNDI resource.

This is Spring 2.5.6SEC03 and the bean itself is annotated @Service for autowiring into other @Component instances. Servlet container in this case is Tomcat 7 but will ultimately be deployed onto Weblogic 10, so while I'd like ideally for a solution to work on both, Weblogic is the must-have.

Am I misusing this feature in Spring 2.5? In general? Is there some bit I'm missing? Something I misunderstand about JNDI? All help is appreciated. Thanks.

Mike Yockey
  • 4,565
  • 22
  • 41

1 Answers1

7

If you are using Spring Stereotype annotations, (@Service, @Component...), then you are probably including in your spring configuration the <context:component-scan /> element to pick them up. It is fine to do this, but it will automatically register a CommonAnnotationBeanPostProcessor with the application context, as stated just above the second note in this link.

The issue with including the CommonAnnotationBeanPostProcessor is that Spring handles the @Resource annotation and will attempt to inject beans from its application context. You can register your own CommonAnnotationBeanPostProcessor bean and tell Spring to allow direct JNDI access to these @Resource's by configuring the bean by setting the alwaysUseJndiLookup property to true.

<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor">
  <property name="alwaysUseJndiLookup" value="true"/>
</bean>

Pay attention to the note in the linked documentation:

NOTE: A default CommonAnnotationBeanPostProcessor will be registered by the "context:annotation-config" and "context:component-scan" XML tags. Remove or turn off the default annotation configuration there if you intend to specify a custom CommonAnnotationBeanPostProcessor bean definition!

nicholas.hauschild
  • 42,483
  • 9
  • 127
  • 120
  • Great, this totally worked! I also discovered that you can force CommonAnnotationBeanPostProcessor to do a JNDI lookup by sprcifying a value for "mappedName" in the annotation body. All that said, and after the work put into this, I learned that our standard corporate deployment process won't support multiple deployment descriptors. I'm supposed to use the same one across all deployments. So, this approach won't work. – Mike Yockey Mar 30 '12 at 19:37