1


I am using java config to configure my Beans:

   @Configuration
public class SpringJavaConfig { 
    @Bean
    public IBrandsApi getBrandsApi(){
        return new BrandsApi();
    }
}

I can see in debug mode while loading that spring aware to the SpringJavaConfig.

In my controller I am using the autowire:

@Controller
@RequestMapping("/api/brands")
public class BrandsController extends BaseController {

BrandsApi brandsApi;

@Autowired
public void setBrandsApi(IBrandsApi brandsApi){
    this.brandsApi = (BrandsApi)brandsApi;
}

}

this is the brands API decleration:

@Transactional
public  class BrandsApi extends BaseApplicationAPI<Object> implements IBrandsApi {

    public BrandsApi(){

    }
}
@Transactional
public interface IBrandsApi {}

this is the exception that i get while loading the tomcat:

 Mar 9, 2011 9:50:54 AM org.apache.catalina.core.StandardContext listenerStart
SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'brandsController': Injection of autowired dependencies failed; nested exception is java.lang.ClassCastException: $Proxy46 cannot be cast to com.affiliates.BrandsApi
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1074)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:580)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
    at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:276)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:197)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:47)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4521)
    at org.apache.catalina.core.StandardContext$1.call(StandardContext.java:5004)
    at org.apache.catalina.core.StandardContext$1.call(StandardContext.java:4999)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:636)
Caused by: java.lang.ClassCastException: $Proxy46 cannot be cast to com.affiliates.BrandsApi
    at com.affiliates.controllers.BrandsController.setBrandsApi(BrandsController.java:37)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:616)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:582)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:282)
    ... 21 more
fatnjazzy
  • 6,070
  • 12
  • 57
  • 83
  • Is there a certain reason why you try to inject via the setter and not via the field? – Thomas Mar 09 '11 at 07:36
  • @Thomas:@Autowired BrandsApi brandsApi - will cause; java.lang.IllegalArgumentException: Can not set com.affiliates.BrandsApi field com.affiliates.controllers.BrandsController.brandsApi to $Proxy41 – fatnjazzy Mar 09 '11 at 07:38
  • OK so you are trying to inject a concrete class that is already wrapped in a proxy. Most likely by Spring itself because you have Java configuration via `@Configurable` enabled. Try letting `BrandsApi` implement an interface and set the type of your field in the controller and the factory method to the interface. – Thomas Mar 09 '11 at 07:41
  • I have edit my post, please re-read – fatnjazzy Mar 09 '11 at 07:53
  • The field in your controller should also be of the interface type. So you don't need to cast in the setter. Then everything should work. You just have to extract all public api methods from BrandsApi to the interface. – Thomas Mar 09 '11 at 07:59
  • Sorry I wasn't fast enough to rewrite it. Can you upvote my comment instead? Thanks! – Thomas Mar 09 '11 at 09:38

2 Answers2

2

Does your BrandsApi use @Transactional or any other kind of AOP? Maybe the problem is you're using a concrete class and not a interface as reference and that could lead a problem when Spring creates some kind of AOP Proxy class.

Check this related question: Spring Autowiring class vs. interface?

Community
  • 1
  • 1
eolith
  • 1,366
  • 10
  • 14
2

See this question: Application context bean.

Why are you downcasting your service to BrandsApi? Shouldn't you be working with interface only?

Community
  • 1
  • 1
Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
  • it was part of my POC, but i did not realize that ill need it for the dependency injection, thanks again – fatnjazzy Mar 09 '11 at 08:13