java.lang.ClassCastException: $Proxy0 cannot be cast to com.performance.service.IntensiveCalculatorService

Spring JIRA | Jeff Fang | 3 years ago
tip
Your exception is missing from the Samebug knowledge base.
Here are the best solutions we found on the Internet.
Click on the to mark the helpful solution and get rewards for you help.
  1. 0

    When a bean whose class type implements an interface is intercepted by a Spring AOP, the bean is not the original bean class type, but is the JDK proxy class which implements the bean's interface. For example, we define an ICalculatorService interface, and an IntensiveCalculatorService class implementing the ICalculatorService interface. And we define an intensiveCalculatorService bean with the IntensiveCalculatorService class in the spring configuraiton file, and intercept the IntensiveCalculatorService.calculator method with spring AOP. The unexpected thing occurs. We cannot cast the "intensiveCalculatorService" bean to an IntensiveCalculatorService class object, though the bean defined as IntensiveCalculatorService class, because it actually is not an object of IntensiveCalculatorService class, but is JDK proxy object which implements ICalculatorService interface. Let's imagine the scenario, a developer A only defined the intensiveCalculatorService bean, and cast the bean to a IntensiveCalculatorService type . It's definitely correct because there is no AOP defined. But the developer A's coworker B want to intercept the IntensiveCalculatorService.calcualtor to do something before the caculator. He defined the AOP aspect in the spring configuration file. The original code of using IntensiveCalculatorService type bean throwed ClassCastException. The severity thing is that developer A and B have no sense of the exception happening. *Though we could use proxy-target-class="true" to force the use of CGLib proxy to solve the problem, I think it needs improvement in spring AOP. Bean's type is changed unexpectedly when Spring AOP is used without proxy-target-class property set. Maybe there are some conerns to try the JDK original proxy mechanism first, and avoid depending the thirdparty lib. At least I think the issue needs enhancement to warn users the unexpected behavior of bean's type being changed.* The code is below: package com.performance.service; public interface ICalculatorService { public void calculator(int count); } package com.performance.service; public class IntensiveCalculatorService implements ICalculatorService { public String type = "intensive"; public void testObjectSelfMethod(){ System. out.println("This is IntensiveCalculatorService Self Method"); } public void calculator(int count){ System. out.println("intensive calculator"); } } The Spring configuration file is below: <aop:config > <aop:aspect id= "TestAspect" ref ="aspectBean"> <aop:pointcut id= "ics" expression="execution(* com.performance.service.IntensiveCalculatorService.calculator(..))" /> <aop:around pointcut-ref="ics" method="aroundMethod"/> </aop:aspect> </aop:config > <bean id="aspectBean" class="com.performance.aspect.TestAspect" /> <bean id= "intensiveCalculatorService" class="com.performance.service.IntensiveCalculatorService" /> The following code will throw ClassCastException in the runtime. IntensiveCalculatorService intensiveCalculatorService = (IntensiveCalculatorService)context.getBean("intensiveCalculatorService" ); Exception in thread "main" java.lang.ClassCastException: $Proxy0 cannot be cast to com.performance.service.IntensiveCalculatorService at com.performance.main.ApplicationMain.main(ApplicationMain.java:20)

    Spring JIRA | 3 years ago | Jeff Fang
    java.lang.ClassCastException: $Proxy0 cannot be cast to com.performance.service.IntensiveCalculatorService
  2. 0

    When a bean whose class type implements an interface is intercepted by a Spring AOP, the bean is not the original bean class type, but is the JDK proxy class which implements the bean's interface. For example, we define an ICalculatorService interface, and an IntensiveCalculatorService class implementing the ICalculatorService interface. And we define an intensiveCalculatorService bean with the IntensiveCalculatorService class in the spring configuraiton file, and intercept the IntensiveCalculatorService.calculator method with spring AOP. The unexpected thing occurs. We cannot cast the "intensiveCalculatorService" bean to an IntensiveCalculatorService class object, though the bean defined as IntensiveCalculatorService class, because it actually is not an object of IntensiveCalculatorService class, but is JDK proxy object which implements ICalculatorService interface. Let's imagine the scenario, a developer A only defined the intensiveCalculatorService bean, and cast the bean to a IntensiveCalculatorService type . It's definitely correct because there is no AOP defined. But the developer A's coworker B want to intercept the IntensiveCalculatorService.calcualtor to do something before the caculator. He defined the AOP aspect in the spring configuration file. The original code of using IntensiveCalculatorService type bean throwed ClassCastException. The severity thing is that developer A and B have no sense of the exception happening. *Though we could use proxy-target-class="true" to force the use of CGLib proxy to solve the problem, I think it needs improvement in spring AOP. Bean's type is changed unexpectedly when Spring AOP is used without proxy-target-class property set. Maybe there are some conerns to try the JDK original proxy mechanism first, and avoid depending the thirdparty lib. At least I think the issue needs enhancement to warn users the unexpected behavior of bean's type being changed.* The code is below: package com.performance.service; public interface ICalculatorService { public void calculator(int count); } package com.performance.service; public class IntensiveCalculatorService implements ICalculatorService { public String type = "intensive"; public void testObjectSelfMethod(){ System. out.println("This is IntensiveCalculatorService Self Method"); } public void calculator(int count){ System. out.println("intensive calculator"); } } The Spring configuration file is below: <aop:config > <aop:aspect id= "TestAspect" ref ="aspectBean"> <aop:pointcut id= "ics" expression="execution(* com.performance.service.IntensiveCalculatorService.calculator(..))" /> <aop:around pointcut-ref="ics" method="aroundMethod"/> </aop:aspect> </aop:config > <bean id="aspectBean" class="com.performance.aspect.TestAspect" /> <bean id= "intensiveCalculatorService" class="com.performance.service.IntensiveCalculatorService" /> The following code will throw ClassCastException in the runtime. IntensiveCalculatorService intensiveCalculatorService = (IntensiveCalculatorService)context.getBean("intensiveCalculatorService" ); Exception in thread "main" java.lang.ClassCastException: $Proxy0 cannot be cast to com.performance.service.IntensiveCalculatorService at com.performance.main.ApplicationMain.main(ApplicationMain.java:20)

    Spring JIRA | 3 years ago | Jeff Fang
    java.lang.ClassCastException: $Proxy0 cannot be cast to com.performance.service.IntensiveCalculatorService

    Root Cause Analysis

    1. java.lang.ClassCastException

      $Proxy0 cannot be cast to com.performance.service.IntensiveCalculatorService

      at com.performance.main.ApplicationMain.main()
    2. com.performance.main
      ApplicationMain.main
      1. com.performance.main.ApplicationMain.main(ApplicationMain.java:20)
      1 frame