2013-03-05 14 views
27

im przy Wiosna społeczna w mojej aplikacji:Nadklasa nie ma pustych konstruktorów ale żadne argumenty dano

<spring.framework.version>3.2.0.RELEASE</spring.framework.version> 
<hibernate.version>4.1.9.Final</hibernate.version> 
<commons-dbcp.version>1.4</commons-dbcp.version> 
<org.springframework.social-version>1.1.0.BUILD-SNAPSHOT</org.springframework.social-version> 
<org.springframework.social.facebook-version>1.1.0.BUILD-SNAPSHOT</org.springframework.social.facebook-version> 
<org.springframework-version>3.2.1.RELEASE</org.springframework-version> 
<org.springframework.security.crypto-version>3.1.3.RELEASE</org.springframework.security.crypto-version> 

Kiedy stosuje

private final Facebook facebook; 

@Inject 
public SearchController(Facebook facebook) { 
    this.facebook = facebook; 
} 

Do mojego HomeController:

@Controller 
public class HomeController { 


    private final Facebook facebook; 

    @Inject 
    public HomeController(Facebook facebook) { 
     this.facebook = facebook; 
    } 

    private static final Logger logger = LoggerFactory.getLogger(HomeController.class); 

    /** 
    * Simply selects the home view to render by returning its name. 
    */ 
    @RequestMapping(value = "/", method = RequestMethod.GET) 
    public String home(Model model) { 
     return "home"; 
    } 

} 

The wtrysk działa tak, jak zamierzano i mogę uzyskać informacje od facebook. Jednak, kiedy stosuje się go do jednego z moich innych Cotrollers jak ten

@Controller 
@Transactional 
@RequestMapping(value = "/search") 
public class SearchController { 

    private static final Logger logger = LoggerFactory.getLogger(SearchController.class); 

    private final Facebook facebook; 

    @Inject 
    public SearchController(Facebook facebook) { 
     this.facebook = facebook; 
    } 

    @PersistenceContext 
    private EntityManager entityManager; 

    ... 

otrzymuję ten błąd:

mar 05, 2013 12:46:36 EM org.apache.catalina.core.StandardWrapperValve invoke 
SEVERE: Servlet.service() for servlet [appServlet] in context with path [/project] threw exception [Request processing failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'searchController' defined in file [C:\Users\Nilsi\Downloads\springsource\vfabric-tc-server-developer-2.7.2.RELEASE\base-instance\wtpwebapps\course_info\WEB-INF\classes\com\courseinfo\project\controller\SearchController.class]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.courseinfo.project.controller.SearchController]: 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] with root cause 
java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given 
    at org.springframework.cglib.proxy.Enhancer.emitConstructors(Enhancer.java:721) 
    at org.springframework.cglib.proxy.Enhancer.generateClass(Enhancer.java:499) 
    at org.springframework.cglib.transform.TransformingClassGenerator.generateClass(TransformingClassGenerator.java:33) 
    at org.springframework.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25) 
    at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216) 
    at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:377) 
    at org.springframework.cglib.proxy.Enhancer.create(Enhancer.java:285) 
    at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:205) 
    at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:111) 
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:477) 
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:362) 
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:322) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:412) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1492) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:524) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461) 
    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.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1117) 
    at org.springframework.web.method.HandlerMethod.createWithResolvedBean(HandlerMethod.java:202) 
    at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:233) 
    at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:55) 
    at org.springframework.web.servlet.handler.AbstractHandlerMapping.getHandler(AbstractHandlerMapping.java:297) 
    at org.springframework.web.servlet.DispatcherServlet.getHandler(DispatcherServlet.java:1091) 
    at org.springframework.web.servlet.DispatcherServlet.getHandler(DispatcherServlet.java:1076) 
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:896) 
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856) 
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:920) 
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:827) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:641) 
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:801) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) 
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99) 
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) 
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002) 
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585) 
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312) 
    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:722) 

Domyślam się, że nie mogę wstrzyknąć facebook do regulatora z adnotacją @ Transakcyjne? Szukałem go, ale nie mogę znaleźć rozwiązania.

+0

Czy to działa, jeśli używasz wtrysku opartego na właściwościach? –

+0

Wow, zadziałało! jeśli umieścisz to jako odpowiedź, oznaczę to jako poprawne. Po prostu usunąłem konstruktora i zmieniono na: @Inject prywatny Facebook facebook; Testowałem wcześniej, ale nie mogłem go uruchomić, ponieważ zmienna była oryginalna. (Był ostateczny w przykładzie kodu Springs, z którego go otrzymałem). – nilsi

Odpowiedz

53

CGlib ma jedno ważne ograniczenie: klasa docelowa musi dostarczyć domyślnego konstruktora.

Jeśli korzystasz z wtrysku opartego na właściwościach zamiast iniekcji konstruktora, problem zniknie.

+40

Poszerzenie tej odpowiedzi: Mogłoby się to udać za pomocą wtrysku konstruktora (który jest preferowany), gdybyś nie dodał "@ Transactional" do kontrolera. Po dodaniu '@ Transactional', AOP kopie i musi zostać utworzony serwer proxy. CGLib potrzebuje domyślnego konstruktora. Innym rozwiązaniem jest skonfigurowanie wiosennych transakcji do używania AspectJ zamiast serwerów proxy. Wymaga to nieco więcej konfiguracji, ale umożliwiłoby transakcje na klasie bez domyślnego konstruktora. –

+3

To jest bardzo dobry komentarz! Myślę, że należy dodać do odpowiedzi. –

+6

Przed wiosną 4, klasy proxy oparte na CGLIB wymagają domyślnego konstruktora. I to nie jest ograniczenie biblioteki CGLIB, ale sama Wiosna. Na szczęście od 4 wiosny nie jest to już problemem. Klasy proxy oparte na CGLIB nie wymagają już domyślnego konstruktora. Zobacz ten artykuł: http://blog.codeleak.pl/2014/07/spring-4-cglib-based-proxy-classes-with-no-default-ctor.html –

0

Właśnie utworzyłem pusty konstruktor domyślny, aby sobie z tym poradzić.