2016-04-26 89 views
1

當我安裝上運行的ext3基於Java 1.8.0_92在CentOS 6.7,我得到以下錯誤部署我的春節4.0.1.RELEASE web應用到Tomcat 8.0.33:奇怪的Tomcat 8部署行爲

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'qualityAuditTokenService' defined in URL [jar:file:/home/www/webapps/ROOT/WEB-INF/lib/product-service-2.0.1-SNAPSHOT.jar!/com/company/product/services/QualityAuditTokenService.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [com.company.workflow.dao.TokenDao]: : No qualifying bean of type [com.company.workflow.dao.TokenDao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.company.workflow.dao.TokenDao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {} 
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:742) 
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:196) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1114) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1017) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:700) 
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760) 
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482) 
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403) 
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306) 
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106) 
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4811) 
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5251) 
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147) 
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:725) 
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:701) 
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:717) 
    at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1092) 
    at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1834) 
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
    at java.lang.Thread.run(Thread.java:745) 
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.company.workflow.dao.TokenDao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {} 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1100) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:960) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:855) 
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:806) 
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:734) 
    ... 28 more 

但是,如果我將安裝完全相同的Web應用程序安裝到在CentOS 6.7上的Java 1.8.0_92上運行的NFS裝載上安裝的Tomcat 8.0.33,則它工作得很好。如果我將它安裝到Centos上的ext3上的Tomcat 7.0.69,Ubuntu上的ext4上的Tomcat 8.0.33以及Windows上的NTFS上,它也可以正常工作。所以它只是把這個錯誤在CentOS上的ext3上的Tomcat 8.0.33上運行。如果這不是我們的實時部署環境,那不會有太大的問題。

所以這顯然不是標準的「缺少註釋」或「JAR類型中缺少的bean類」之類的問題,儘管我很樂意聽到這種情況下的建議,以免我錯過了某些東西。

這個部署的奇怪之處在於Spring bean在不同的文件系統上以不同的順序創建。在這項工作中的版本,在日誌文件中會顯示以下的用Spring記錄刷爆:

DEBUG DefaultListableBeanFactory:449 - Creating instance of bean 'tokenDaoHbm' 
DEBUG DefaultListableBeanFactory:249 - Returning cached instance of singleton bean 'sessionFactory' 
DEBUG DefaultListableBeanFactory:249 - Returning cached instance of singleton bean 'searchSessionFactory' 
DEBUG DefaultListableBeanFactory:750 - Autowiring by type from bean name 'tokenDaoHbm' via constructor to bean named 'sessionFactory' 
DEBUG DefaultListableBeanFactory:523 - Eagerly caching bean 'tokenDaoHbm' to allow for resolving potential circular references 
DEBUG DefaultListableBeanFactory:249 - Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor' 
DEBUG DefaultListableBeanFactory:249 - Returning cached instance of singleton bean 'org.springframework.cache.config.internalCacheAdvisor' 
DEBUG AnnotationTransactionAttributeSource:108 - Adding transactional method 'TokenDaoHbm.update' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; '' 
DEBUG InfrastructureAdvisorAutoProxyCreator:551 - Creating implicit proxy for bean 'tokenDaoHbm' with 0 common interceptors and 1 specific interceptors 
DEBUG JdkDynamicAopProxy:117 - Creating JDK dynamic proxy: target source is SingletonTargetSource for target object [[email protected]] 
DEBUG DefaultListableBeanFactory:477 - Finished creating instance of bean 'tokenDaoHbm' 

這是一個能夠滿足了它創建的依賴豆 - 在拋出異常的版本,這個bean創建是值得注意的是它的缺席。

TL; DR

那麼,怎樣才能操作系統,文件系統類型和/或網絡延遲改變Spring的創建豆的順序(或以其他方式打破它的相關性分析)?這肯定是在WAR文件中提供的東西(以及與它打包的Spring版本)?

我試圖通過@ComponentScan和@Qualifier來影響bean創建無濟於事 - 還有其他方法嗎?

此問題與下面鏈接的問題類似,但沒有發佈解決方案(並且它們遇到了Tomcat 7而不是8問題)。 Need help debugging Tomcat 7 application error

任何與此有關的幫助非常感謝,因爲這一個真讓我煩惱! :-D

回答

0

我現在有一個解決方案(因此發佈了一個答案),但它屁股很蠢,我仍然沒有解釋爲什麼這是必要的(所以我會保存爲更優雅的解決方案或完整的解釋)。

原來發行57129對ASF的Bugzilla提出了我的問題是關於: https://bz.apache.org/bugzilla/show_bug.cgi?id=57129

然而,概括那裏的情況下,WAR中的多個JAR文件包含不同版本的同一類文件。這意味着改變順序會改變應用程序的行爲 - 這不是理想的。

在我的情況下,有問題的類TokenDaoHbm只在WAR文件中存在一次。只是這樣,如果在Spring實例化qualityAuditTokenService bean時Tomcat類加載器尚未加載product-dao-hibernate-2.0.1-SNAPSHOT JAR文件,那麼您將得到一個NoSuchBeanDefinitionException異常。當然,Spring和/或Tomcat必須知道所有類必須在bean實例化開始之前加載?

<Resources> 
    <PreResources className="org.apache.catalina.webresources.FileResourceSet" 
       base="${catalina.base}/webapps/ROOT/WEB-INF/lib/product-dao-hibernate-2.0.1-SNAPSHOT.jar" 
       webAppMount="/WEB-INF/lib/product-dao-hibernate-2.0.1-SNAPSHOT.jar" /> 
</Resources> 

如果任何人都可以進一步闡明:

因此,要解決我的問題,我根據馬克·托馬斯在ASF錯誤張貼的意見放在下面我的應用程序的context.xml在WAR在此我很樂意將它們標記爲已接受的答案。