I've gotten Spring 2.5.1 + EJB3 to work on both JBoss and Glassfish. Though, I've also at times run into issues similar to the above (see my thread on this).
Like you, I also placed spring.jar into ${JBOSS_HOME}/server/default/lib.
Here's my current (trivial) setup that works on JBoss 4.2.0.GA (minus the import statements).
My bean interface:
package foo.ejb; public interface Service { public String getVersion(); }
My Bean implementation:
package foo.ejb; @Stateless(name = "service") public class ServiceBean implements Service { @Autowired private Delegate delegate; public String getVersion() { return delegate.getVersion(); } }
Delegate is a dependency of ServiceBean :
package foo.ejb; public class Delegate { public String getVersion() { return "1.0"; } }
My beanRefContext.xml
:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean class="org.springframework.context.support.ClassPathXmlApplicationContext"> <constructor-arg type="java.lang.String" value="ejbApplicationContext.xml" /> </bean> </beans>
And my ejbApplicationContext.xml :
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="delegate" class="foo.ejb.Delegate" /> </beans>
And finally, to configure Spring to inject into my EJBs, I used Spring 2.5.1's SpringBeanAutowiringInterceptor . Here's my /META-INF/ejb-jar.xml
:
<?xml version="1.0" encoding="UTF-8"?> <ejb-jar version="3.0" 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/ejb-jar_3_0.xsd"> <interceptors> <interceptor> <interceptor-class>org.springframework.ejb.interceptor.SpringBeanAutowiringInterceptor</interceptor-class> </interceptor> </interceptors> <assembly-descriptor> <interceptor-binding> <ejb-name>*</ejb-name> <interceptor-class>org.springframework.ejb.interceptor.SpringBeanAutowiringInterceptor</interceptor-class> </interceptor-binding> </assembly-descriptor> </ejb-jar>
That all goes into foo-ejb.jar .
Next the stuff that goes into foo-web.war , starting with my controller:
package foo.web; @Controller public class IndexController { /** * Or "service/remote" on JBoss. For Glassfish, remove the suffix. */ @EJB(mappedName = "service/local") private Service service; @RequestMapping("/index.html") public void index(ModelMap model) { model.addAttribute("version", service.getVersion()); } }
The Freemarker template that comprises the view for the above:
<html> <body> <p>Version: ${version}</p> </body> </html>
Now, an important point : I had problems on both Glassfish and JBoss getting the JNDI lookup correct because of prefixes and suffixes. The most relevant part of my foo-servlet.xml shows how I avoid the "java:comp/env" prefix:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"> <!-- Use a custom JNDI bean factory configured not to prepend lookups with "java:comp/env" --> <bean id="jndiFactory" class="org.springframework.jndi.support.SimpleJndiBeanFactory"> <property name="resourceRef" value="false" /> </bean> <!-- Configure the CommonAnnotationBeanPostProcessor to always use JNDI lookup (for EJBs) and use the custom JNDI bean factory above. --> <bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"> <property name="alwaysUseJndiLookup" value="true" /> <property name="jndiFactory" ref="jndiFactory" /> </bean> <!-- Since we're turning off "annotation-config" in the context:component-scan below, we need to explicitly configure an AutowiredAnnotationBeanPostProcessor. --> <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" /> <!-- Configure annotation-based component scanning, instantiation and dependency injection. --> <context:component-scan base-package="com.talikos.ese.web.controllers" annotation-config="false" /> <!-- Rest of Spring MVC (view resolver, etc.) configuration goes here. --> </beans>
Hope this (lengthy post) helps. I really should blog this.