Spring ProGuard 构建中 TransactionAttributeSource 的 NoUniqueBeanDefinitionException
Spring NoUniqueBeanDefinitionException for TransactionAttributeSource on ProGuard build
我有一个基于 Maven 的 Java Web 应用程序,其中包含 Spring 5.2.0.RELEASE。当我尝试使用 ProGuard 6.2.2 混淆代码时,它构建成功。但是,当我尝试在 Apache Tomcat.
上部署混淆的 war 文件时出现以下错误
[ERROR] 2020-06-08 09:23:27.748 [localhost-startStop-1] ContextLoader [][][] Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'messageSource' defined in class path resource [resources/spring/portal-context.xml]: BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.transaction.config.internalTransactionAdvisor' defined in class path resource [org/springframework/transaction/annotation/ProxyTransactionManagementConfiguration.class]: Unsatisfied dependency expressed through method 'transactionAdvisor' parameter 0; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.springframework.transaction.interceptor.TransactionAttributeSource' available: expected single matching bean but found 2: org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,transactionAttributeSource
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:512) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean[=11=](AbstractBeanFactory.java:323) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:207) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.initMessageSource(AbstractApplicationContext.java:732) ~[spring-context-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538) ~[spring-context-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:401) ~[spring-web-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:292) [spring-web-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:103) [spring-web-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4770) [catalina.jar:8.5.40]
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5236) [catalina.jar:8.5.40]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [catalina.jar:8.5.40]
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:754) [catalina.jar:8.5.40]
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:730) [catalina.jar:8.5.40]
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:734) [catalina.jar:8.5.40]
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:980) [catalina.jar:8.5.40]
at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1851) [catalina.jar:8.5.40]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_201]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_201]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_201]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_201]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_201]
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.transaction.config.internalTransactionAdvisor' defined in class path resource [org/springframework/transaction/annotation/ProxyTransactionManagementConfiguration.class]: Unsatisfied dependency expressed through method 'transactionAdvisor' parameter 0; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.springframework.transaction.interceptor.TransactionAttributeSource' available: expected single matching bean but found 2: org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,transactionAttributeSource
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:787) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:528) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1338) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean[=11=](AbstractBeanFactory.java:323) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:207) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.aop.framework.autoproxy.BeanFactoryAdvisorRetrievalHelper.findAdvisorBeans(BeanFactoryAdvisorRetrievalHelper.java:91) ~[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findCandidateAdvisors(AbstractAdvisorAutoProxyCreator.java:109) ~[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors(AnnotationAwareAspectJAutoProxyCreator.java:92) ~[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator.shouldSkip(AspectJAwareAdvisorAutoProxyCreator.java:101) ~[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessBeforeInstantiation(AbstractAutoProxyCreator.java:251) ~[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInstantiation(AbstractAutowireCapableBeanFactory.java:1141) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation(AbstractAutowireCapableBeanFactory.java:1114) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:506) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
... 22 more
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.springframework.transaction.interceptor.TransactionAttributeSource' available: expected single matching bean but found 2: org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,transactionAttributeSource
at org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:220) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1265) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1207) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:874) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:778) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:528) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1338) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean[=11=](AbstractBeanFactory.java:323) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:207) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.aop.framework.autoproxy.BeanFactoryAdvisorRetrievalHelper.findAdvisorBeans(BeanFactoryAdvisorRetrievalHelper.java:91) ~[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findCandidateAdvisors(AbstractAdvisorAutoProxyCreator.java:109) ~[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors(AnnotationAwareAspectJAutoProxyCreator.java:92) ~[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator.shouldSkip(AspectJAwareAdvisorAutoProxyCreator.java:101) ~[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessBeforeInstantiation(AbstractAutoProxyCreator.java:251) ~[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInstantiation(AbstractAutowireCapableBeanFactory.java:1141) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation(AbstractAutowireCapableBeanFactory.java:1114) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:506) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
... 22 more
Spring 本身创建了获取错误的 bean。所以我无法追踪窃听代码。你能帮我解决这个问题吗?
我的 proguard.conf 和 context.xml 文件如下
proguard.conf
-injars portal.war
-outjars smartgate.war
-dontshrink
-dontoptimize
-dontusemixedcaseclassnames
-dontpreverify
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
#-skipnonpubliclibraryclasses
#-dontobfuscate
-forceprocessing
-optimizations !class/marking/final
-adaptresourcefilenames **.xsd,**.wsdl,**.xml,**.properties,META-INF/MANIFEST.MF,META-INF/spring.*
-adaptresourcefilecontents **.xsd,**.wsdl,**.xml,**.properties,META-INF/MANIFEST.MF,META-INF/spring.*
-keepdirectories
#-renamesourcefileattribute SourceFile
#-keep class *
-keep class com.foo.** {
void set*(***);
void set*(int, ***);
boolean is*();
boolean is*(int);
*** get*();
*** get*(int);
}
-keep class **MailThread {
public void run;
}
-keep class !com.foo.** { *; }
-keep class com.foo.model.entity.** { *; }
-keep class com.foo.service.log.FatalLogAspect { *; }
-keep class com.foo.service.MailService** { *; }
-keepclassmembers class com.foo.service.MailService** { *; }
-keep class com.foo.smartgate.service.adapter.SMSCAdapter** { *; }
-keepclassmembers class com.foo.smartgate.service.adapter.SMSCAdapter** { *; }
-keep class com.foo.smartgate.filter.** { *; }
-keep class com.foo.service.context.** { *; }
-keep class com.foo.**.bean.** { *; }
-keep class com.foo.**.ws.** { *; }
-keep class com.foo.util.Custom** { *; }
-keep class com.foo.util.ConnectionUtils { *; }
-keepattributes RuntimeVisibleAnnotations,Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
-keep @javax.persistence.* class * {
*;
}
-keep @org.springframework.transaction.annotation.Transactional class *
-keep @org.springframework.stereotype.Service class *
-keep @org.springframework.stereotype.Controller class *
-keep @org.springframework.beans.factory.annotation.Autowired class *
-keep @org.springframework.web.bind.annotation.ResponseBody class *
-keep @org.springframework.web.bind.annotation.RequestMapping class *
-keep @org.springframework.stereotype.Repository class *
-keep @javax.annotation.Resource class *
-keep @javax.persistence.Entity class *
-keep @javax.persistence.Table class *
-keep @javax.persistence.Id class *
-keep @javax.persistence.GeneratedValue class *
-keep @javax.persistence.Column class *
-keep @javax.persistence.Transient class *
-keep @org.springframework.ws.server.endpoint.annotation.Endpoint class *
-keep @org.springframework.ws.server.endpoint.annotation.PayloadRoot class *
-keep @org.springframework.ws.server.endpoint.annotation.ResponsePayload class *
-keepclassmembers class * {
@javax.annotation.Resource *;
@org.springframework.beans.factory.annotation.Autowired *;
@org.springframework.beans.factory.annotation.Value *;
}
-keepclassmembers enum * {
*;
}
-keepclassmembernames class * {
com.foo.service.context.ConfigurationManager config;
java.lang.Class class$(java.lang.String);
java.lang.Class class$(java.lang.String, boolean);
}
-keepclasseswithmembers class com.foo.config.** {*;}
-keep class com.foo.utils.locker.** { *; }
-keepclassmembers class com.foo.utils.locker.** { *; }
-keepnames class com.foo.utils.locker.** { *; }
-dontwarn **
-dontnote "!DuplicateClassPrinter*"
context.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" xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p" xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
<context:annotation-config />
<context:component-scan base-package="com.foo" />
<aop:aspectj-autoproxy proxy-target-class="true" />
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:resources/locale/messages" />
<property name="defaultEncoding" value="UTF-8" />
</bean>
<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/edge" />
<bean class="com.foo.service.context.PropertiesUtil">
<property name="location" value="classpath:resources/application.properties" />
</bean>
<bean id="log4jFilter" class="com.foo.filter.Log4jFilter" />
<bean id="contextApplicationContextProvider"
class="com.foo.service.context.ApplicationContextProvider"></bean>
<bean id="errorLogger" class="com.foo.service.log.FatalLogAspect" />
<mvc:annotation-driven />
<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang" />
</bean>
<bean class="com.foo.context.LocaleInterceptor">
</bean>
<bean class="com.foo.filter.ViewHandlerInterceptor">
</bean>
</mvc:interceptors>
<!-- freemarker config -->
<bean id="freemarkerConfig"
class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="/views">
</property>
<property name="freemarkerSettings">
<props>
<prop key="template_update_delay">10</prop>
<prop key="default_encoding">UTF-8</prop>
</props>
</property>
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<property name="order" value="2" />
<property name="cache" value="true" />
<property name="prefix" value="" />
<property name="contentType" value="text/html;charset=UTF-8" />
<property name="requestContextAttribute" value="context" />
<property name="suffix">
<value>.ftl</value>
</property>
</bean>
<bean id="methodHandlerExceptionResolver"
class="org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver">
<property name="messageConverters">
<list>
<bean
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
</list>
</property>
</bean>
<bean
class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="order" value="1" />
<property name="defaultViews">
<list>
<bean
class="org.springframework.web.servlet.view.json.MappingJackson2JsonView" />
</list>
</property>
</bean>
<bean class="com.foo.context.LocaleResolver"
id="localeResolver">
</bean>
<aop:config>
<aop:aspect id="aspectLoggging" ref="errorLogger">
<aop:pointcut id="pointCutAfterThrowing"
expression="within(@org.springframework.stereotype.Controller *)" />
<aop:after-throwing method="afterThrowing"
throwing="e" pointcut-ref="pointCutAfterThrowing" />
</aop:aspect>
</aop:config>
</beans>
感谢您抽出时间。
这是因为定义了两次事务管理器(xml和java)
从 context.xml 中删除以下行解决了问题。
<tx:annotation-driven transaction-manager="transactionManager" />
事务管理器的java端
/*
* https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/annotation/EnableTransactionManagement.html
* <tx:annotation-driven transaction-manager="transactionManager" />
*/
@EnableTransactionManagement
如果不混淆,这通常不会引起问题。删除 xml 行解决了问题。
我有一个基于 Maven 的 Java Web 应用程序,其中包含 Spring 5.2.0.RELEASE。当我尝试使用 ProGuard 6.2.2 混淆代码时,它构建成功。但是,当我尝试在 Apache Tomcat.
上部署混淆的 war 文件时出现以下错误[ERROR] 2020-06-08 09:23:27.748 [localhost-startStop-1] ContextLoader [][][] Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'messageSource' defined in class path resource [resources/spring/portal-context.xml]: BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.transaction.config.internalTransactionAdvisor' defined in class path resource [org/springframework/transaction/annotation/ProxyTransactionManagementConfiguration.class]: Unsatisfied dependency expressed through method 'transactionAdvisor' parameter 0; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.springframework.transaction.interceptor.TransactionAttributeSource' available: expected single matching bean but found 2: org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,transactionAttributeSource
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:512) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean[=11=](AbstractBeanFactory.java:323) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:207) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.initMessageSource(AbstractApplicationContext.java:732) ~[spring-context-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538) ~[spring-context-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:401) ~[spring-web-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:292) [spring-web-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:103) [spring-web-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4770) [catalina.jar:8.5.40]
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5236) [catalina.jar:8.5.40]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [catalina.jar:8.5.40]
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:754) [catalina.jar:8.5.40]
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:730) [catalina.jar:8.5.40]
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:734) [catalina.jar:8.5.40]
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:980) [catalina.jar:8.5.40]
at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1851) [catalina.jar:8.5.40]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_201]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_201]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_201]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_201]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_201]
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.transaction.config.internalTransactionAdvisor' defined in class path resource [org/springframework/transaction/annotation/ProxyTransactionManagementConfiguration.class]: Unsatisfied dependency expressed through method 'transactionAdvisor' parameter 0; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.springframework.transaction.interceptor.TransactionAttributeSource' available: expected single matching bean but found 2: org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,transactionAttributeSource
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:787) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:528) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1338) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean[=11=](AbstractBeanFactory.java:323) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:207) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.aop.framework.autoproxy.BeanFactoryAdvisorRetrievalHelper.findAdvisorBeans(BeanFactoryAdvisorRetrievalHelper.java:91) ~[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findCandidateAdvisors(AbstractAdvisorAutoProxyCreator.java:109) ~[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors(AnnotationAwareAspectJAutoProxyCreator.java:92) ~[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator.shouldSkip(AspectJAwareAdvisorAutoProxyCreator.java:101) ~[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessBeforeInstantiation(AbstractAutoProxyCreator.java:251) ~[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInstantiation(AbstractAutowireCapableBeanFactory.java:1141) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation(AbstractAutowireCapableBeanFactory.java:1114) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:506) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
... 22 more
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.springframework.transaction.interceptor.TransactionAttributeSource' available: expected single matching bean but found 2: org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,transactionAttributeSource
at org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:220) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1265) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1207) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:874) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:778) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:528) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1338) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean[=11=](AbstractBeanFactory.java:323) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:207) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.aop.framework.autoproxy.BeanFactoryAdvisorRetrievalHelper.findAdvisorBeans(BeanFactoryAdvisorRetrievalHelper.java:91) ~[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findCandidateAdvisors(AbstractAdvisorAutoProxyCreator.java:109) ~[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors(AnnotationAwareAspectJAutoProxyCreator.java:92) ~[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator.shouldSkip(AspectJAwareAdvisorAutoProxyCreator.java:101) ~[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessBeforeInstantiation(AbstractAutoProxyCreator.java:251) ~[spring-aop-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInstantiation(AbstractAutowireCapableBeanFactory.java:1141) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation(AbstractAutowireCapableBeanFactory.java:1114) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:506) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
... 22 more
Spring 本身创建了获取错误的 bean。所以我无法追踪窃听代码。你能帮我解决这个问题吗?
我的 proguard.conf 和 context.xml 文件如下
proguard.conf
-injars portal.war
-outjars smartgate.war
-dontshrink
-dontoptimize
-dontusemixedcaseclassnames
-dontpreverify
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
#-skipnonpubliclibraryclasses
#-dontobfuscate
-forceprocessing
-optimizations !class/marking/final
-adaptresourcefilenames **.xsd,**.wsdl,**.xml,**.properties,META-INF/MANIFEST.MF,META-INF/spring.*
-adaptresourcefilecontents **.xsd,**.wsdl,**.xml,**.properties,META-INF/MANIFEST.MF,META-INF/spring.*
-keepdirectories
#-renamesourcefileattribute SourceFile
#-keep class *
-keep class com.foo.** {
void set*(***);
void set*(int, ***);
boolean is*();
boolean is*(int);
*** get*();
*** get*(int);
}
-keep class **MailThread {
public void run;
}
-keep class !com.foo.** { *; }
-keep class com.foo.model.entity.** { *; }
-keep class com.foo.service.log.FatalLogAspect { *; }
-keep class com.foo.service.MailService** { *; }
-keepclassmembers class com.foo.service.MailService** { *; }
-keep class com.foo.smartgate.service.adapter.SMSCAdapter** { *; }
-keepclassmembers class com.foo.smartgate.service.adapter.SMSCAdapter** { *; }
-keep class com.foo.smartgate.filter.** { *; }
-keep class com.foo.service.context.** { *; }
-keep class com.foo.**.bean.** { *; }
-keep class com.foo.**.ws.** { *; }
-keep class com.foo.util.Custom** { *; }
-keep class com.foo.util.ConnectionUtils { *; }
-keepattributes RuntimeVisibleAnnotations,Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
-keep @javax.persistence.* class * {
*;
}
-keep @org.springframework.transaction.annotation.Transactional class *
-keep @org.springframework.stereotype.Service class *
-keep @org.springframework.stereotype.Controller class *
-keep @org.springframework.beans.factory.annotation.Autowired class *
-keep @org.springframework.web.bind.annotation.ResponseBody class *
-keep @org.springframework.web.bind.annotation.RequestMapping class *
-keep @org.springframework.stereotype.Repository class *
-keep @javax.annotation.Resource class *
-keep @javax.persistence.Entity class *
-keep @javax.persistence.Table class *
-keep @javax.persistence.Id class *
-keep @javax.persistence.GeneratedValue class *
-keep @javax.persistence.Column class *
-keep @javax.persistence.Transient class *
-keep @org.springframework.ws.server.endpoint.annotation.Endpoint class *
-keep @org.springframework.ws.server.endpoint.annotation.PayloadRoot class *
-keep @org.springframework.ws.server.endpoint.annotation.ResponsePayload class *
-keepclassmembers class * {
@javax.annotation.Resource *;
@org.springframework.beans.factory.annotation.Autowired *;
@org.springframework.beans.factory.annotation.Value *;
}
-keepclassmembers enum * {
*;
}
-keepclassmembernames class * {
com.foo.service.context.ConfigurationManager config;
java.lang.Class class$(java.lang.String);
java.lang.Class class$(java.lang.String, boolean);
}
-keepclasseswithmembers class com.foo.config.** {*;}
-keep class com.foo.utils.locker.** { *; }
-keepclassmembers class com.foo.utils.locker.** { *; }
-keepnames class com.foo.utils.locker.** { *; }
-dontwarn **
-dontnote "!DuplicateClassPrinter*"
context.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" xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p" xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
<context:annotation-config />
<context:component-scan base-package="com.foo" />
<aop:aspectj-autoproxy proxy-target-class="true" />
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:resources/locale/messages" />
<property name="defaultEncoding" value="UTF-8" />
</bean>
<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/edge" />
<bean class="com.foo.service.context.PropertiesUtil">
<property name="location" value="classpath:resources/application.properties" />
</bean>
<bean id="log4jFilter" class="com.foo.filter.Log4jFilter" />
<bean id="contextApplicationContextProvider"
class="com.foo.service.context.ApplicationContextProvider"></bean>
<bean id="errorLogger" class="com.foo.service.log.FatalLogAspect" />
<mvc:annotation-driven />
<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang" />
</bean>
<bean class="com.foo.context.LocaleInterceptor">
</bean>
<bean class="com.foo.filter.ViewHandlerInterceptor">
</bean>
</mvc:interceptors>
<!-- freemarker config -->
<bean id="freemarkerConfig"
class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="/views">
</property>
<property name="freemarkerSettings">
<props>
<prop key="template_update_delay">10</prop>
<prop key="default_encoding">UTF-8</prop>
</props>
</property>
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<property name="order" value="2" />
<property name="cache" value="true" />
<property name="prefix" value="" />
<property name="contentType" value="text/html;charset=UTF-8" />
<property name="requestContextAttribute" value="context" />
<property name="suffix">
<value>.ftl</value>
</property>
</bean>
<bean id="methodHandlerExceptionResolver"
class="org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver">
<property name="messageConverters">
<list>
<bean
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
</list>
</property>
</bean>
<bean
class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="order" value="1" />
<property name="defaultViews">
<list>
<bean
class="org.springframework.web.servlet.view.json.MappingJackson2JsonView" />
</list>
</property>
</bean>
<bean class="com.foo.context.LocaleResolver"
id="localeResolver">
</bean>
<aop:config>
<aop:aspect id="aspectLoggging" ref="errorLogger">
<aop:pointcut id="pointCutAfterThrowing"
expression="within(@org.springframework.stereotype.Controller *)" />
<aop:after-throwing method="afterThrowing"
throwing="e" pointcut-ref="pointCutAfterThrowing" />
</aop:aspect>
</aop:config>
</beans>
感谢您抽出时间。
这是因为定义了两次事务管理器(xml和java)
从 context.xml 中删除以下行解决了问题。
<tx:annotation-driven transaction-manager="transactionManager" />
事务管理器的java端
/*
* https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/annotation/EnableTransactionManagement.html
* <tx:annotation-driven transaction-manager="transactionManager" />
*/
@EnableTransactionManagement
如果不混淆,这通常不会引起问题。删除 xml 行解决了问题。