Mocking class in Spring 3.2 causes "No qualifying bean of type X" found - spring

Im trying to mock the HttpClient implementation using the Spring 3.1 profiles and by using EasyMock, but the Spring container complains it cant find a bean with right type. Have I configured the mock wrong? If I replace the EasyMock bean with the actually implementation it is injected correctly, it seems like the EasyMock method doesnt create a bean of right type. All help very appreciated!
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.apache.http.client.HttpClient] 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:986)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:856)
<beans profile="development,developmentthomas,test,integration,webtest,accept">
<bean id="httpClient" class="org.easymock.EasyMock" factory-method="createMock">
<constructor-arg value="org.apache.http.client.HttpClient" />
</bean>
</beans>
<beans profile="thomasciserver,testserverlocaloleg,testservercioleg,preprod,production,testservercithomas,testserverlocalthomas,localthomasclean,testserver,productionthomas">
<bean id="httpClient" class="org.apache.http.impl.client.DefaultHttpClient"/>
</beans>

i think the problem lies within the factory method.
have a look at this post Autowiring of beans generated by EasyMock factory-method? ithink this will solve your problem

See the spring-test. It has org.springframework.mock.http.client.MockClientHttpRequest. The org.springframework.mock package has a whole bushel of things that will save you from reinventing the wheel.

Related

Unable to Autowire brave.Tracer inside Spring boot Application

I am working on Spring boot application and I tried to Autowire Tracer object to get the traceId, but its raised the following exception. why??
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'brave.Tracer' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
I used the Tracer in a lot of projects and its always working with no issues!!
Spring boot container is not able to resolve the implementation of your autowired interface in this case. Please annotate your implementation class with spring stereotype annotations.
For e.g We provide #Reposiory for dao classes, #Service for service classes & #Component as a generic one. This will solve your problem. If you still face any issues, Just share your code snippet.

How is s3Client auto-wired in this project?

I'm writing a Spring application in which I want to use the AWS S3 client. All I need to do is generate signed URLs. The code that uses the S3 client is straightforward and I wrote it already, but I'm trying to figure out the proper way to instantiate it, as in, the Spring way.
I found this project on GitHub called spring-boot-aws that seems to do what I need. On FileArchiveService.java it has these two lines:
#Autowired
private AmazonS3Client s3Client;
When I add those lines to my project, I expectedly get this error:
Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'screenshotsController': Unsatisfied dependency expressed through field 's3Client'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.amazonaws.services.s3.AmazonS3Client' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
I searched spring-boot-aws trying to figure out how is this bean provided and I cannot find it. I'm including the same dependency, org.springframework.cloud:spring-cloud-aws-context:1.2.1.RELEASE but that's not enough.
Any ideas how that project is doing it or how I should do it?
I tried coping the aws-config.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aws-context="http://www.springframework.org/schema/cloud/aws/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/cloud/aws/context
http://www.springframework.org/schema/cloud/aws/context/spring-cloud-aws-context-1.0.xsd">
<aws-context:context-credentials>
<aws-context:simple-credentials access-key="${accessKey:}" secret-key="${secretKey:}"/>
</aws-context:context-credentials>
<aws-context:context-resource-loader/>
</beans>
and a modified AwsResourceConfig.java:~
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
#Configuration
#ImportResource("classpath:/aws-config.xml")
public class AwsResourceConfig {
}
but I still get the same error.

Struts 2 action method intercepting using Spring AOP

I'm trying to intercept the Struts2 Action class's methods to print the method start and method end indication statement using Spring AOP.
The fact is , my Struts2 actions instance are also Spring beans (Struts2 and Spring integration done as per the url: http://www.mkyong.com/struts2/struts-2-spring-integration-example/). AOP configurations is as below:
<bean id="testAdviceBean" class="com.tcs.oss.plugins.SimpleAdvice">
</bean>
<aop:config>
<aop:aspect ref="testAdviceBean" order="200">
<aop:pointcut id="testPoint2"
expression="execution(java.lang.String com.test..DeviceAction.*(..))"
/>
<aop:around pointcut-ref="testPoint2" method="loggingAdvice" />
</aop:aspect>
</aop:config>
In the advice method loggingAdvice , I'm trying to print the method START and method END statement using the ProceedingJoinPoint API.The advice method is not called at all ... instead it's ending up with the error below after going through the struts default interceptor chain ...
But I'm getting the below ERROR TRACE:
09:26:49,093 TRACE
[org.springframework.beans.factory.support.DefaultListableBeanFactory]
(http-01h3463916-172.20.211.235-8543-5) Ignoring constructor [public
org.apache.struts2.dispatcher.ServletDispatcherResult(java.lang.String)]
of bean 'org.apache.struts2.dispatcher.ServletDispatcherResult':
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name
'org.apache.struts2.dispatcher.ServletDispatcherResult': Unsatisfied
dependency expressed through constructor argument with index 0 of type
[java.lang.String]: : No matching bean of type [java.lang.String]
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
matching bean of type [java.lang.String] found for dependency:
expected at least 1 bean which qualifies as autowire candidate for
this dependency. Dependency annotations: {}
09:26:49,095 TRACE
[org.springframework.beans.factory.support.DefaultListableBeanFactory]
(http-01h3463916-172.20.211.235-8543-5) Not autowiring property
'urlHelper' of bean
'org.apache.struts2.dispatcher.ServletDispatcherResult' by name: no
matching bean found
09:26:49,100 DEBUG
[org.apache.struts2.dispatcher.ServletDispatcherResult]
(http-01h3463916-172.20.211.235-8543-5) Forwarding to location
/General/error.jsp
If I just remove the above AOP configurations, It's just working fine. What I'm doing wrong ?
The advice method is not called because Action class was extending from ActionSupport class which in turn has a interface implementations... So , in this case, A JDK proxy was created for the Action class -- This type of proxy doesn't have any method specific(non-inheritance) to the Action class.
Adding proxy-target-class="true" attribute, in the AOP configuration, made the Spring to generate CGLib(need to add CGLib in the Classpath) based proxy.. which now has the non-inheritance methods too, of the Action class.
After a bunch of digging, I think I found the issue (if you're using Spring to help with AOP, even if you're not you're probably going to need a different ObjectFactory), long and short of it is that you need to make sure that the struts ObjectFactory is setup properly:
<constant name="struts.objectFactory" value="org.apache.struts2.spring.StrutsSpringObjectFactory" />
<constant name="struts.objectFactory.spring.autoWire.alwaysRespect" value="true"/>
or
<constant name="struts.objectFactory" value="spring" />
<constant name="struts.objectFactory.spring.autoWire.alwaysRespect" value="true"/>
source: http://www.javawebdevelop.com/3294124/

Autowiring fails IllegalArgument un-safe operation exception

I am getting the following exception after upgrading my Spring jars.
org.springframework.web.servlet.DispatcherServlet - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.integration.transformer.HeaderEnricher#4': Cannot create inner bean '(inner bean)' of type [org.springframework.integration.transformer.HeaderEnricher$MessageProcessingHeaderValueMessageProcessor] while setting constructor argument with key [#{partnerHeaderKey}]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#19': Injection of resource dependencies failed; nested exception is java.lang.IllegalArgumentException: Can not set com.follett.fheg.coursemateriallookup.coursematerial.data.dao.PartnerDAO field com.follett.fheg.coursemateriallookup.coursematerial.integration.headerenricher.PartnerHeaderEnricher.partnerDAO to org.springframework.integration.transformer.HeaderEnricher$MessageProcessingHeaderValueMessageProcessor
at org.springframework.beans.factory.support.BeanDefinitionValue Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#19': Injection of resource dependencies failed; nested exception is java.lang.IllegalArgumentException: Can not set com.follett.fheg.coursemateriallookup.coursematerial.data.dao.PartnerDAO field com.follett.fheg.coursemateriallookup.coursematerial.integration.headerenricher.PartnerHeaderEnricher.partnerDAO to org.springframework.integration.transformer.HeaderEnricher$MessageProcessingHeaderValueMessageProcessor
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:306)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1146)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:271)
... 40 more
Caused by: java.lang.IllegalArgumentException: Can not set com.follett.fheg.coursemateriallookup.coursematerial.data.dao.PartnerDAO field com.follett.fheg.coursemateriallookup.coursematerial.integration.headerenricher.PartnerHeaderEnricher.partnerDAO to org.springframework.integration.transformer.HeaderEnricher$MessageProcessingHeaderValueMessageProcessor
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:146)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:150)
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:37)
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:57)
at java.lang.reflect.Field.set(Field.java:657)
at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:150)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:303)
... 44 more
From what I have read I needed to add #Component annotation to my bean and/or create the in my application context - neither of these approaches have worked. The DAO it is referring to is declared like so <bean id="partnerDAO" class="com.follett.fheg.coursemateriallookup.coursematerial.data.dao.impl.PartnerDAOImpl"/>. If I remove the #Component annotation I get a red line under #Autowired and a message that says "Autowired members must be defined in the valid spring bean (#Component/#Service etc..)", but after doing that i still get the errors.
I am using Spring integration so the bean to auto-wire is defined there.
<integration:header-enricher>
<integration:header name="#{partnerHeaderKey}" method="getPartner">
<bean class="com.follett.fheg.coursemateriallookup.coursematerial.integration.headerenricher.PartnerHeaderEnricher"/>
</integration:header>
</integration:header-enricher>
Any thoughts or help is appreciated! Thank you.
Note: the application runs fine if I drop back down to Spring 2.1.4.RELEASE even without declaring the #Component or <bean> in the application context.
UPDATE
As blackpanther mentions below I need a element in the application context. I failed to mention that I DO Have this <context:component-scan base-package="com.follett.fheg.coursemateriallookup.coursematerial.integration.headerenricher" /> There is another for the DAO's as well <context:component-scan base-package="com.follett.fheg.coursemateriallookup.coursematerial.data.dao" />
Not exactly, just putting the annotation #Component does not mean that that Java class will have it's properties autowired. In order to use the #Component annotation effectively, you must tell Spring where to look for these classes. This is done by the <context:component-scan base-package="package.name" /> tag in your Spring configuration.
I would have a look at this article as it may help you.
You can specify #Qualifier on top of the bean declaration inside the component like below.
#Autowired
#Qualifier("loginService")
private ILoginService loginService;
loginService is the name of the bean in the .xml context file.
I was able to resolve this issue by using #Component annotation as well as modifying the way the beans were created in the context.
For some reason when I moved the <bean class=""> out of the <integration:header> and added a ref-"" attribute it started working just fine. I am getting a different error, but I was able to get the application running.
old way
<integration:header-enricher>
<integration:header name="#{partnerHeaderKey}" method="getPartner">
<bean class="com.follett.fheg.coursemateriallookup.coursematerial.integration.headerenricher.Partner HeaderEnricher"/>
</integration:header>
</integration:header-enricher>
new way
<integration:header-enricher>
<integration:header name="#{partnerHeaderKey}" method="getPartner" ref="myBean">
</integration:header>
</integration:header-enricher>
</integration:chain>
<bean id="myBean" class="com.follett.fheg.coursemateriallookup.coursematerial.integration.headerenricher.PartnerHeaderEnricher"/>

Understand initialization time behaviour of mvc:annotation-driven

I am trying to debug an issue with RequestMappingHandlerAdapter initialization and I have come to a conclusion by searching the Web that it is getting initialized from mvc:annotation-driven xml entry. Can anyone explain me briefly, how this initialization works i.e. what happens when the parser parses mvc:annotation-driven? Or point me to the code that does it and I will trace it through.
Some more context on this:
I was trying to get RequestMappingHandlerAdapter from the context via autowire but could not. It gave me:
No matching bean of type [org.springframework.web.servlet.mvc.method.annotation.RequestMappingH
andlerAdapter]
expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
Found this thread, but the solution does not does not work: Spring, Jackson and Customization (e.g. CustomDeserializer)
I am using: Spring 3.1.3
This is what my servlet xml file looks like ...
<context:annotation-config />
<context:component-scan base-package="com.xyz" />
<mvc:annotation-driven />
Thanks,
Parth
I would think it would cause either the AnnotationConfigApplicationContext or AnnotationConfigWebApplicationContext to search for the annotated classes and create/graph them. One way to figure things out would be to make a bean that throws a RuntimeException in its default constructor and see what the stack trace looks like.

Resources