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:
Code:
package foo.ejb;
public interface Service {
public String getVersion();
}
My Bean implementation:
Code:
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:
Code:
package foo.ejb;
public class Delegate {
public String getVersion() {
return "1.0";
}
}
My beanRefContext.xml:
Code:
<?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:
Code:
<?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:
Code:
<?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:
Code:
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:
Code:
<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:
Code:
<?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.