10

I have mixed stack: EJB and Spring. For autowiring Spring to EJBs I use SpringBeanAutowiringInterceptor (not sure if that could affect the problem I have).

Whlie trying to autowire beans in a following way:

@Scope(proxyMode=ScopedProxyMode.TARGET_CLASS, value="singleton")
@Repository
public class ClassA imlpements IfA {
    ...
}


@Scope(value="singleton")
@Repository
public class ClassB {
    @Autowired
    private ClassA classA;

    ...
}

I get error:

Could not autowire field: private ClassA ClassB.classA; nested exception is java.lang.IllegalArgumentException: Can not set ClassA field ClassB.classA to com.sun.proxy.$Proxy257. Please see server.log for more details.

As far as I've understood, the problem is that JDK proxies are used (as ClassA implements interface IfA), while I'd need cglib ones.

But I don't get it. Based on the docs, the annotation: @Scope(proxyMode=ScopedProxyMode.TARGET_CLASS, should do the job here.

Well and it's not an option for me to use interfaces (as a field type).

Any idea how to force cglib proxying here?

EDIT:

Not sure if it's relevant, but I'm running glassfish 3.1.x.

And stacktrace (partial, as I can't expose all the class names here:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'classB': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private ClassA ClassB.classA; nested exception is java.lang.IllegalArgumentException: Can not set ClassA field ClassB.classA to com.sun.proxy.$Proxy257.
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:288)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1116)
    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.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:912)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:855)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:770)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:486)
    ... 89 more
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private ClassA ClassB.classA; nested exception is java.lang.IllegalArgumentException: Can not set ClassA field ClassB.classA to com.sun.proxy.$Proxy257. Please see server.log for more details.
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:514)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)
    ... 100 more
Caused by: java.lang.IllegalArgumentException: Can not set ClassA field ClassB.classA to com.sun.proxy.$Proxy257
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:164)
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:168)
    at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81)
    at java.lang.reflect.Field.set(Field.java:741)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:510)
    ... 102 more
Peter Butkovic
  • 11,143
  • 10
  • 57
  • 81

1 Answers1

12

You should not use aop scoped proxies for singletons.

Use <aop:aspectj-autoproxy proxy-target-class="true" /> or @EnableAspectJAutoProxy(proxyTargetClass=true) in your spring configuration file or class to force cglib proxies.

Jose Luis Martin
  • 10,459
  • 1
  • 37
  • 38
  • none of the 2 suggested worked for me: neither marking `ClassA` with `@EnableAspectJAutoProxy(proxyTargetClass=true)` nor ``. Still, just for curiosity: why should I not use singletons? – Peter Butkovic Aug 14 '14 at 12:07
  • ClassA is not a configuration class. You should use @EnableAspectJAutoProxy only in configuration classes. However the tag should work. Could you post the relevant part of your context file?. Has no sense to use scoped proxies for singletos see note in http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html#beans-factory-scopes-other-injection – Jose Luis Martin Aug 14 '14 at 12:20
  • @PeterButkovic if aspectj tag don't work, your proxy don't comes from an `AutoProxyCreator`. Do you know who is creating the proxy for ClassA? – Jose Luis Martin Aug 14 '14 at 12:54
  • 1
    OK, so asking for xml config file was the right point, as I've found out, that `` was missing => my attempts with annotations were useless. So I came to point, where things start to work for me: ` ` and ` `. However I wonder if there is a less verbose way, like enabling: `` globaly, rather than per class. – Peter Butkovic Aug 14 '14 at 13:00
  • @PeterButkovic IMHO you should concentrate in configuring the proxy factory that creates the repository proxies, usually an AutoproxyCreator and forgot the scoped proxies, singleton scope never change, so you really don't need thems. – Jose Luis Martin Aug 14 '14 at 13:18