Spring - Classcast exception as a CGLIB proxy cannot be forced

Here is the script that turns me on.

  • I have a class that has a search method - createOther ()
  • createOther should create an object of type Other. Other OtherInterface tools and, in addition, have a doSomething method that is marked as @Async
  • Since Other implements OtherInterface, Spring gives me a JDK proxy, which I cannot use as Other.
  • Spring docs suggest using <aop:config proxy-target-class="true"> - but I'm new to this and use one that doesn't seem to help.

Question: how do I tell Spring that I need a CGLib proxy designed for the Other class?

Below is the code with a classcastexception error.

  Exception in thread "main" java.lang.ClassCastException: $Proxy4 cannot be cast to scratch.Other at scratch.App$$EnhancerByCGLIB$$82d16307.createOther(<generated>) at scratch.App.main(App.java:19) 

App.java:

 public class App { public Other createOther() { throw new UnsupportedOperationException(); } public static void main(final String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("appcontext.xml"); App app = (App) context.getBean("app"); Other oth = app.createOther(); oth.doSomething(); System.out.println("Other created"); } 

}

** Other.java **

 public interface OtherInterface { } class Other implements OtherInterface { @Async public void doSomething() { System.out.println("did something"); } } 

** appcontext.xml **

 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/schema/task" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <aop:config proxy-target-class="true"></aop:config> <bean name="app" class="scratch.App"> <lookup-method bean="otherBean" name="createOther" /> </bean> <bean name="otherBean" class="scratch.Other" scope="prototype"> </bean> <task:executor id="workflowExecutorSvcPool" pool-size="5-50" queue-capacity="1000" keep-alive="60" /> <task:annotation-driven executor="workflowExecutorSvcPool" /> </beans> 
+4
source share
3 answers

Everything seems fine - this is the right way to tell spring to use cglib proxies. In fact, the documentation states that it will make cglib proxies by default. The only requirement is to have cglib in your classpath. Make sure you have the cglib jar.

+1
source

The task:annotation-driven element must support its own proxy-target-class attribute, which must be set to true for cglib proxies, for example

+1
source
 Other oth = app.createOther(); 

This line is a problem. Since the returned object is actually a proxy, the createOther() method should return OtherInterface , which will implement the proxy.

It tries to use the proxy version of the OtherInterface class for the Other class and does not work.

0
source

Source: https://habr.com/ru/post/1347421/


All Articles