Spring AOP IllegalArgumentException: Cannot convert value of type [$Proxy12 - spring

I am trying to configure one advice in an existing spring project.
Following configuration works fine for a single package but when pointcut expression try to apply that advice on all packages its giving following error.
My Configuration:
<aop:config>
<aop:pointcut id="loggingPointcut" expression="execution(* com.abc.businessprocess.operation..*.execute(..))" />
<aop:advisor id="methodLoggingAdvisor" advice-ref="methodLoggingAdvice" pointcut-ref="loggingPointcut" />
</aop:config>
I tried with annotation also but it was giving same error.
I tried with CGLIB also even after using that its giving same error.
Error:
Caused by: org.springframework.beans.TypeMismatchException: Failed to convert property value of type [$Proxy12 implementing com.fmr.ast.common.businessprocess.util.Timeable,com.fmr.ast.common.businessprocess.operation.Operation,com.fmr.commons.taskmanager.core.Task,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised] to required type [com.fmr.ips.businessprocess.operation.goalsetup.GetLeveledIRGExpInc] for property 'getRawDetailedLeveledExpInc'; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [$Proxy12 implementing com.fmr.ast.common.businessprocess.util.Timeable,com.fmr.ast.common.businessprocess.operation.Operation,com.fmr.commons.taskmanager.core.Task,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised] to required type [com.fmr.ips.businessprocess.operation.goalsetup.GetLeveledIRGExpInc] for property 'getRawDetailedLeveledExpInc': no matching editors or conversion strategy found
at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:391)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapableBeanFactory.java:1289)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1250)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1010)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:472)
... 33 more
Caused by: java.lang.IllegalArgumentException: Cannot convert value of type [$Proxy12 implementing com.fmr.ast.common.businessprocess.util.Timeable,com.fmr.ast.common.businessprocess.operation.Operation,com.fmr.commons.taskmanager.core.Task,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised] to required type [com.fmr.ips.businessprocess.operation.goalsetup.GetLeveledIRGExpInc] for property 'getRawDetailedLeveledExpInc': no matching editors or conversion strategy found
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:231)
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:138)
at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:386)
... 37 more

Looking at the exception trace this is what I suspect:
GetLeveledIRGExpInc is a concrete class that implements three interfaces: Timeable, Operation, Task. You have a bean of this type declared in your context, which gets proxied because of your AOP config. This means that the runtime type of the bean won't be GetLeveledIRGExpInc any more, it will be $Proxy12 (JDK proxy) which still implements the above three interfaces, but is not a subtype of the concrete class GetLeveledIRGExpInc.
There is another bean somewhere in your context that needs a bean of this type to be injected into a property named getRawDetailedLeveledExpInc. When Spring tries to inject the proxied bean into that property, it fails, because the property's type is incompatible with the bean's runtime type.
The fundamental problem is that you try to apply a very generic logging aspect using JDK proxying mechanism which can only advise methods declared on interfaces. Try using <aop:config proxy-target-class="true"> so that classes without implemented interfaces can be advised as well. This would resolve the above detailed problem, as the generated CGLIB proxy for GetLeveledIRGExpInc will actually be a subtype of it. (Don't forget to add cglib to your dependencies for this to work.)

Related

Bean's property is not setting from util:list object

I have declared following list using spring util namespace in my spring configuration file:
<util:list id="childList">
<ref bean="child1"/>
<ref bean="child2"/>
<ref bean="child3"/>
</util:list>
where all reference bean are marked with #Componant annotation and their respective beans are creating. But whenever I am trying to Autowired any beans property like:
#Component
public class ListTest{
#Autowired
#Qualifier("childList")
private List<IParent> list;
public List<IParent> getList() {
return list;
}
}
Gives exception as: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'listTest': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private java.util.List com.spring3.componentScanFilterTest.ListTest.list; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.spring3.componentScanFilterTest.IParent] found for dependency [collection of com.spring3.componentScanFilterTest.IParent]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true), #org.springframework.beans.factory.annotation.Qualifier(value=childList)}
But instead of #Autowired and #Qualifier if I use as:
#Resource(name="childList")
It works. Why? As per my understanding #Autowired is used to autowire the property matching by type and #Qualifier is used to select any one bean from multiple ambiguous beans.
Please explain.
Spring docs says.
As a specific consequence of this semantic difference, beans that are themselves defined as a collection or map type cannot injected through #Autowired, because type matching is not properly applicable to them. Use #Resource for such beans, referring to the specific collection or map bean by unique name.
Hope this clear your doubt.
Type matching is not properly applicable to beans which defined as collection.
If you intend to express annotation-driven injection by name, do not primarily use #Autowired - even if is technically capable of referring to a bean name through #Qualifier values. Instead, prefer the JSR-250 #Resource annotation which is semantically defined to identify a specific target component by its unique name, with the declared type being irrelevant for the matching process.
As a specific consequence of this semantic difference, beans which are themselves defined as a collection or map type cannot be injected via #Autowired since type matching is not properly applicable to them. Use #Resource for such beans, referring to the specific collection/map bean by unique name.
Here:
http://docs.spring.io/spring/docs/2.5.x/reference/beans.html#beans-autowired-annotation-qualifiers
You are trying to get list of all beans of type Parent that have the qualifier "childList".

Cannot convert value of type [org.hibernate.impl.SessionFactoryImpl] to required type [com.liferay.portal.kernel.dao.orm.SessionFactory]

I got this exception!!!
Caused by: java.lang.IllegalStateException: Cannot convert value of type [org.hibernate.impl.SessionFactoryImpl] to required type [com.liferay.portal.kernel.dao.orm.SessionFactory] for property 'sessionFactory': no matching editors or conversion strategy found
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:289)
at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:154)
at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:452)
... 41 more
Do you have any solution?
One of the beans that you pass sessionFactory to them require the Liferay one instead of the Hibernate one.
There are 2 possible mistakes:
You made a mistake in wiring - fix that by passing Lifray's SessionFactory (create one if you don't have one already)
The mistake is in Java class imports - fix the imports

Spring AOP - Error Generating proxies

I'm using spring AOP's around advice to capture processing time of a transaction. I'm getting the following error during application startup
error creating bean "coreMessageResourceAccesor"
Could not generate CGLIB subclass of class
[class org.springframework.context.support.MessageSourceAccessor]:
Common causes of this problem include using a final class or a non-visible class;
nested exception is java.lang.IllegalArgumentException:
Superclass has no null constructors but no arguments were given
I identified what the problem is with the help of this thread. But I cannot change coreMessageResourceAccesor bean to use setter based injection because its using a spring class & that class doesn't have no arg constructor
Below is the configuration for the bean
<bean id="coreMessageSourceAccessor"
class="org.springframework.context.support.MessageSourceAccessor" >
<constructor-arg type="org.springframework.context.MessageSource"
ref="coreMessageSource" />
</bean>
I would really appreciate if someone could help. Thanks for your time.
You don't need really need to configure MessageSourceAccessor accessor as a bean, it's generally easier to instantiate it manually as required. So rather than inject the MessageSourceAccessor into your beans, inject the raw MessageSource, and then wrap it in a MessageSourceAccessor as required (i.e. using new MessageSourceAccessor(messageSource)).
You can then put the advice around the MessageSource rather than the MessageSourceAccessor, which will work better. Also, MessageSourceAccessor will not itself add any significant processing time, it's just a thin wrapper around MessageSource.

Error while injecting a Spring bean into a JSF ManagedBean

I have a JSF ManagedBean which has a property that should be set by Spring. However, I get the following error:
Caused by: javax.el.ELException: java.lang.IllegalArgumentException: Cannot convert persistence.AuthDao#2f6e6ad9 of type class $Proxy166 to class persistence.AuthDao
at com.sun.el.ExpressionFactoryImpl.coerceToType(ExpressionFactoryImpl.java:68)
at com.sun.faces.el.ELUtils.coerce(ELUtils.java:536)
at com.sun.faces.mgbean.BeanBuilder$Expression.evaluate(BeanBuilder.java:592)
at com.sun.faces.mgbean.ManagedBeanBuilder$BakedBeanProperty.set(ManagedBeanBuilder.java:606)
... 57 more
Caused by: java.lang.IllegalArgumentException: Cannot convert persistence.AuthDao#2f6e6ad9 of type class $Proxy166 to class persistence.AuthDao
at com.sun.el.lang.ELSupport.coerceToType(ELSupport.java:397)
at com.sun.el.ExpressionFactoryImpl.coerceToType(ExpressionFactoryImpl.java:66)
I have the ELresolver in faces-config.xml.
<managed-bean>
<managed-bean-name>authController</managed-bean-name>
<managed-bean-class>controllers.AuthController</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>authDao</property-name>
<value>#{authDao}</value>
</managed-property>
</managed-bean>
<application>
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>
It seems that it can find the class, but the class is of another type ($Proxy166?, not sure where that comes from).
PS: Removing the ELResolver seems to do the trick; I thought explicitly providing managed-bean in faces-config.xml would override ELResolver. Is there any way of both of these to coexist, then? Similarly, if I provide both annotation and XML configuration for a bean, which one of these is preferred, or is there a way to merge them, provide some properties in annotation, some in XML?
PPS: After adding interfaces and changing my current classes to implement them, I get the following error:
Error occurred during deployment: Exception while loading the app :
java.lang.IllegalStateException: ContainerBase.addChild: start:
org.apache.catalina.LifecycleException:
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'authDao' defined in ServletContext resource
[/WEB-INF/applicationContext.xml]: Initialization of bean failed;
nested exception is
org.springframework.beans.ConversionNotSupportedException: Failed to
convert property value of type '$Proxy157 implementing
persistence.UserDao,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised'
to required type 'persistence.UserDaoImpl' for property 'userDao';
nested exception is java.lang.IllegalStateException: Cannot convert
value of type [$Proxy157 implementing
persistence.UserDao,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised]
to required type [persistence.UserDaoImpl] for property 'userDao': no
matching editors or conversion strategy found. Please see server.log
for more details.
This is a proxy of your class. You are implementing an interface, so spring creates a proxy around the interface, but you are trying to inject by concrete type. Switch to the interface instead (in the managed bean).
If you really need for some reason to inject by concrete class, you can use #Scoped(proxyMode=ScopeProxyMode.TARGET_CLASS)

Spring bean with no id or name

I'm reviewing some Spring code, and I see a few bean defs that do not have an id or a name.
The person who did it is not around to ask.
The application is working fine.
I am not familiar what this necessarily means.
Anybody know if this means anything in particular?
Some beans are not required to be accessed by other beans in the context file or programmatically. So as mentioned by JacobM, they don't require an id or name as they're not referenced.
Such an example would be a PropertyPlaceholderConfigurer, which reads a property file, then allows for runtime property replacement in the context definition.
The example definition would be
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="myapp.properties" />
</bean>
The JavaDoc provides further documentation on this object, but further on in the file you can reference properties from your file by just using the standard template replace placeholder ${...}.
One possibility is that you can define a bean in place, and so you don't need an id since you don't need to refer to it from anywhere else. Say I have a Foo object that takes a Bar property:
<bean id="foo" class="Foo">
<property name="bar">
<bean class="Bar">
</property>
</bean>
The Bar bean doesn't need a name because it's only used to set that one property.
Check the possibility of auto-wiring. An other bean could reference the unnamed bean by having the autowire property set to byType.
This is just a guess. Without a concrete example, I can't say any more.
The id and name attributes are optional and are used to reference the bean definition from other definitions. Look at the official Spring documentation for more detail.
take a look at https://docs.spring.io/spring/docs/4.3.12.RELEASE/spring-framework-reference/htmlsingle/#beans-beanname it says,
You are not required to supply a name or id for a bean. If no name or id is supplied explicitly, the container generates a unique name for that bean. However, if you want to refer to that bean by name, through the use of the ref element or Service Locator style lookup, you must provide a name. Motivations for not supplying a name are related to using inner beans and autowiring collaborators.
Also, Beans such as BeanPostProcessor, BeanFactoryPostProcessor and PropertyPlaceholderConfigurer are automatically detected by application context and typically won't have name
If you consider any spring bean, Spring mandates it to have an identifier. In case, if you have not provided any identifier (via id or name attribute) to a bean in your configuration, you won't run into exceptions. Spring will manage such situation by assigning a default identifier. it has BeanNameGenerator to assign default name. <bean class="com.package.name.TestBean"> will be named as "com.package.name.TestBean" #Bean kind of beans will have its method name as bean name
thus, in your code, for some reason, you can skip naming few beans and the code still works if you are accessing those beans with their default name
credits : https://www.javacodegeeks.com/2013/02/spring-bean-names.html
Beans without id or name can still be referenced by the class name. Spring names those beans automatically using the class name and if there is more than one bean of the same class it appends a number to them.
Anonymous beans are usually defined inside a property tag, but if they're just there maybe there's autowiring configured in some other beans.
Anyway, I think adding a name or id to those beans won't break your application.
As a couple of people mentioned above, not all bean-grabbing is based on name/ID; some of it is based on type. For example, there is a method
BeanFactoryUtils.beansOfTypeIncludingAncestors(...)
that grabs all the beans of some given type. This is used for example by the Spring Web MVC DispatcherServlet (among many other places) to discover beans by type, such as HandlerMappings, HandlerAdapters, HandlerExceptionResolvers and so forth. Contrast this with cases where the bean must have a specific well-known name/ID to be found, such as the LocaleResolver (ID must be "localeResolver" or it won't be found) and ThemeResolver (ID must be "themeResolver" or it won't be found).
Beans defined without name and ID can be accessed with a generated ID (full package name and class name), for example:
bean defined as
<bean class="pl.finsys.initOrder.TestBeanImpl">
can be accessed by
TestBean bean = (TestBean) ctx.getBean("pl.finsys.initOrder.TestBeanImpl");
//Bean Cfg File without Bean id
<bean class="com.ds.DemoBean">
<property name="msg" value="Hello"/>
</bean>
//We can Access
Object obj=factory.getBean("com.ds.DemoBe
its not a mandatory to provide java Bean Id..If we are not providing Bean Id,our Container Provides the Default Been Id.Default Bean Id look like as
"(Package Name).(Bean Class Name)#N"where N=0,1,2,......etc.
It seems there is a subtle difference between unnamed and named bean behaviour. If you have an XML config file imported twice, each named bean will be created only once, but an unnamed bean will be created as many times as its definition is included. When trying to autowire such a bean by type, it leads to errors like this:
No qualifying bean of type [your.class.Name] is defined: expected single matching bean but found 4

Resources