2012-12-27 39 views
1

我們有一個Spring管理的bean與@EJB場@EJB注入到一個Spring bean在JBoss中

import org.springframework.security.web.authentication.logout.LogoutHandler; 

public class MyLogoutHandler extends LogoutHandler { 

    @EJB(name="MyService") 
    private MyService myService; 

    ... 
} 

而在我們的Spring XML中,我們有

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

這個工作在WebLogic和Glassfish,但不在JBoss 7.1.2中(請參閱stacktrace @ [1])。

通過Spring代碼挖掘,似乎它轉換爲JBoss似乎不支持的Java EE標準容器前綴「java:comp/env /」[2]的JNDI名稱(即「MyService」)。從JBoss日誌,似乎只支持以下內容:

java:global/my-ear/my-ejb/MyService!my,package.MyServiceLocal 
java:app/my-ejb/MyService!my,package.MyServiceLocal 
java:module/MyService!my,package.MyServiceLocal 
java:global/my-ear/my-ejb/MyService 
java:app/my-ejb/MyService 
java:module/MyService 

然而,這些似乎除了那些前綴工作的「java:模塊」,這導致javax.naming.NameNotFoundException。

現在的問題是,有沒有爲我注入我EJB豆成我的Spring Bean的方式,這將 一)仍允許相同的代碼庫,以在WebLogic中運行,和Glassfish 灣)最好,而不必重寫每個@EJB注入,或者沒有爲每個將被注入到我的spring bean中的@EJB bean指定一個ref-bean?

[1]

08:20:18,697 ERROR [org.springframework.web.context.ContextLoader] (MSC service thread 1-6) Context initialization failed: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.filterChains': Cannot resolve reference to bean 'org.springframework.security.web.DefaultSecurityFilterChain#0' while setting bean property 'sourceList' with key [0]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.web.DefaultSecurityFilterChain#0': Cannot resolve reference to bean 'logoutFilter' while setting constructor argument with key [3]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'logoutFilter' defined in ServletContext resource [/WEB-INF/security-filter.xml]: Cannot resolve reference to bean 'myLogoutHandler' while setting constructor argument with key [0]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myLogoutHandler': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'MyService' is defined: not found in JNDI environment 
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:106) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveManagedList(BeanDefinitionValueResolver.java:353) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:153) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1360) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1118) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:567) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913) [spring-context-3.1.1.RELEASE.jar:3.1.1.RELEASE] 
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464) [spring-context-3.1.1.RELEASE.jar:3.1.1.RELEASE] 
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:385) [spring-web-3.1.1.RELEASE.jar:3.1.1.RELEASE] 
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:284) [spring-web-3.1.1.RELEASE.jar:3.1.1.RELEASE] 
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:111) [spring-web-3.1.1.RELEASE.jar:3.1.1.RELEASE] 
    at org.apache.catalina.core.StandardContext.contextListenerStart(StandardContext.java:3392) [jbossweb-7.0.13.Final.jar:] 
    at org.apache.catalina.core.StandardContext.start(StandardContext.java:3850) [jbossweb-7.0.13.Final.jar:] 
    at org.jboss.as.web.deployment.WebDeploymentService.start(WebDeploymentService.java:90) [jboss-as-web-7.1.1.Final.jar:7.1.1.Final] 
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811) 
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) [rt.jar:1.6.0_32] 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) [rt.jar:1.6.0_32] 
    at java.lang.Thread.run(Thread.java:662) [rt.jar:1.6.0_32] 
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.web.DefaultSecurityFilterChain#0': Cannot resolve reference to bean 'logoutFilter' while setting constructor argument with key [3]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'logoutFilter' defined in ServletContext resource [/WEB-INF/security-filter.xml]: Cannot resolve reference to bean 'myLogoutHandler' while setting constructor argument with key [0]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myLogoutHandler': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'MyService' is defined: not found in JNDI environment 
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:106) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveManagedList(BeanDefinitionValueResolver.java:353) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:153) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:616) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:148) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1035) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:939) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:322) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
... 25 more 
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'logoutFilter' defined in ServletContext resource [/WEB-INF/security-filter.xml]: Cannot resolve reference to bean 'myLogoutHandler' while setting constructor argument with key [0]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myLogoutHandler': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'MyService' is defined: not found in JNDI environment 
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:106) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveManagedList(BeanDefinitionValueResolver.java:353) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:153) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:616) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:148) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1035) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:939) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:322) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
... 39 more 
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myLogoutHandler': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'MyService' is defined: not found in JNDI environment 
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:306) [spring-context-3.1.1.RELEASE.jar:3.1.1.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:322) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
... 53 more 
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'MyService' is defined: not found in JNDI environment 
    at org.springframework.jndi.support.SimpleJndiBeanFactory.getBean(SimpleJndiBeanFactory.java:117) [spring-context-3.1.1.RELEASE.jar:3.1.1.RELEASE] 
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:410) [spring-context-3.1.1.RELEASE.jar:3.1.1.RELEASE] 
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$EjbRefElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:698) [spring-context-3.1.1.RELEASE.jar:3.1.1.RELEASE] 
    at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:150) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87) [spring-beans-3.1.0.RELEASE.jar:3.1.0.RELEASE] 
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:303) [spring-context-3.1.1.RELEASE.jar:3.1.1.RELEASE] 
... 61 more 

[2] http://grepcode.com/file/repo1.maven.org/maven2/org.springframework/spring-context/3.1.1.RELEASE/org/springframework/jndi/JndiLocatorSupport.java#JndiLocatorSupport.convertJndiName%28java.lang.String%29

+0

我想你可以創建一個新的* BeanFactory繼承SimpleJndiBeanFactory,它將使用你需要的jndi名稱。 – mabn

+0

謝謝mabn。這就是我現在正在做的事情,直到有人提出更好的建議。我希望有更好的東西在那裏,因爲我認爲在JBoss中EJB注入Spring bean似乎是一個常見的用例。 –

回答

0

一些奇怪的原因,現在它工作。 JBoss現在可以查找我的服務EJB。奇怪的是,我認爲我做的唯一事情就是讓我的JAXRS類@Stateless(來自@RequestScoped)。雖然我沒有對我的服務bean做任何修改,但是修改JAXRS類似乎也讓我的Spring bean也可以使用這些服務EJB。

編輯:對於那些尋找替代的答案,在jboss中,java:module/env /似乎可以作爲java:comp/env /的替代工作。

+1

在Web模塊中,整個模塊對應於java:comp。在EJB模塊中,每個單獨的bean都有自己的java:comp。 java:模塊總是對應於當前的完整模塊,無論是Web還是ejb模塊。所以是的,在web模塊的情況下,java:comp和java:模塊是相同的。 –

+0

謝謝@ArjanTijms。但奇怪的是,我使用的服務可以通過java:comp/env /訪問,但如果我的JAXRS資源類沒有使用無狀態或有狀態註釋,則不能通過我的JAXRS資源類訪問。通過使用Stateless/Stateful註釋JAXRS資源類,現在可以從我的JAXRS資源類查找我的java:com/env/service對象。 –