You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@wicket.apache.org by Igor Vaynberg <ig...@gmail.com> on 2007/09/06 00:25:32 UTC

Re: [Wicket-user] Wicket requiring one of my Spring managed beans to have a default constructor

this is not a requirement of wicket-spring integration, it is a requirement
of cglib.

when you want to @SpringBean a class that is not an interface wicket cannot
use jdk to create the proxy, so it uses cglib to create the proxy. looks
like cglib is messing up somehow. unfortunately this is outside of scope of
wicket. a work around would be for you to extract an interface and use that
with @SpringBean instead.

-igor


On 9/5/07, Maris Orbidans <sm...@ime.lv> wrote:
>
>
> Actually it's a problem if @SpringBean annotation creates new objects of
> class that is supposed to be a *singleton*.
> Is it really impossible to create a proxy class without creating a new
> object of delegatee ?
>
> Here is a discussion we had about it:
>
>
> [23:10] <Smike> I just noticed that @SpringBean creates a new instance
> of my Spring bean
> [23:10] <Smike> it's not good, after all Spring pojos are supposed to be
> singletons
> [23:11] <Hali_303> Smike: it should not create a new instance if the
> Spring bean is a singleton
> [23:12] <Smike> it does
> [23:12] <Hali_303> Smike: not all Spring beans are singletons, far from
> it. Spring has many scopes, singleton scope is just one out of many scopes
> [23:12] <Smike> it's default, isnt it ?
> [23:12] <Hali_303> yes
> [23:13] <Hali_303> how do you know that it's creating multiple instances?
> [23:13] <Smike> my beans have default scope
> [23:14] <Smike> breakpoints in constructor and logging statements
> [23:14] <Smike> and I have seen the same issue discussed in mail list
> [23:14] <Smike> where Igor says cglib needs to create a new object
> [23:15] <Smike> so every bean needs a default constructor
> [23:15] <Hali_303> could you give me a pointer to this discussion?
> [23:16] <Smike> here is the title  [Wicket-user] Wicket requiring one of
> my Spring managed beans     to have a default constructor
> [23:18] <Smike> it should only lookup a bean from spring context,   why
> it needs to create a new object... I have no idea
> [23:18] <Hali_303> Smike: yeah I think what Igor says is right
> [23:19] <Smike> why it can't use existing object ?
> [23:19] * srufle (n=chatzill@ip68-99-93-211.ph.ph.cox.net) Quit ( Read
> error: 110 (Connection timed out) )
> [23:19] * srufle_______ is now known as srufle
> [23:19] <Hali_303> Smike: regarding jdk proxies vs cglib
> [23:19] <Hali_303> Smike: yeah exactly, I don't really see the
> connection between that thread and your problem
> [23:20] <Hali_303> the guy in that thread did not complain about
> multiple instances of singleton beans
> [23:20] <Smike> the problem is that @SpringBean creates a new class
> [23:20] <Smike> and that thread only confirms that
> [23:21] <Hali_303> it's not SpringBean, its cglib that creates one
> [23:21] <Hali_303> and should create it only once, not every time use
> inject the bean
> [23:21] <Hali_303> and should create it only once, not every time use
> inject the bean
> [23:21] <Smike> yes,  @SpringBean annotation creates a proxy based on
> cglib
> [23:22] <Smike> ok,   but  I can't believe that there is no way to
> create a proxy without creating a new class
> [23:23] <Smike> of course, I am not reflection expert
> [23:24] <Smike> but I think it's possible
> [23:24] <Smike> at least with JDK proxy class
> [23:24] <Smike> I have never used cglib though
> [23:25] <Smike> so....  I think this is important issue and should be
> fixed
> [23:26] <pertl> Smike: I remember having a similar issue when using a
> bean without interface...maybe it's related to your issue... I got
> multiple instances of one singleton bean... once I used the interface /
> implementation pattern (UserDAO + UserDAOImpl) everything worked...
> [23:26] <Smike> yes could be
> [23:27] <pertl> Smike: give it a try ... use the interface but let
> spring instantiate the implementation class... maybe it works out
> [23:28] <Hali_303> I'm using that too, and it works
> [23:28] <Hali_303> I've even used prototype beans and that worked too
> [23:28] <Smike> sounds good,  ok,  I'll try
>
> > you have to have an empty constructor. afaik it doesnt have to be
> > public. this is so that cglib can create a proxy, i dont think there
> > is a way around it.
> >
> > -igor
> >
> >
> > On 5/9/07, * Matt Welch* <matthewcwelch@gmail.com
> > <ma...@gmail.com>> wrote:
> >
> >     I am using the @SpringBean annotation to instantiate Spring
> >     dependencies in my wicket pages but I have one page that is giving
> >     me a error that I'm having trouble dealing with. Here's an example.
> >
> >     The Wicket page class:
> >
> >     public class Viewer extends WebPage {
> >
> >         @SpringBean(name = "contentSettings")
> >         private ContentSettings contentSettings;
> >
> >         @SpringBean(name = "learningItemRepository")
> >         private LearningItemRepository learningItemRepository;
> >
> >         public Viewer() {
> >
> >             //add some simple components to the page
> >
> >         }
> >     }
> >
> >     The vast majority of the time, my Spring managed beans are
> >     implementations of interfaces and not standalone concrete classes,
> >     however, in this particular situation I have about a dozen or so
> >     beans that don't need to follow that pattern.
> >
> >     "LearningRepository" is an interface with a concrete
> >     implementation. "ContentSettings" on the other hand is a
> >     standalone concrete class. Both classes are properly setup in my
> >     Spring configuration xml files and I have a suite of unit tests
> >     which load the classes using Spring so I know that they "should"
> >     work. In fact, "LearningRepository" does work fine, but I'm
> >     getting an error from Wicket with regards to the the
> >     ContentSettings class:
> >
> >     ---------------------------------------------
> >
> >     java.lang.IllegalArgumentException: Superclass has no null
> >     constructors but no arguments were given
> >     at net.sf.cglib.proxy.Enhancer.emitConstructors (Enhancer.java:718)
> >     at net.sf.cglib.proxy.Enhancer.generateClass(Enhancer.java:499)
> >     at
> >     net.sf.cglib.core.DefaultGeneratorStrategy.generate(
> DefaultGeneratorStrategy.java:25)
> >     at net.sf.cglib.core.AbstractClassGenerator.create
> >     (AbstractClassGenerator.java:216)
> >     at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
> >     at net.sf.cglib.proxy.Enhancer.create(Enhancer.java:285)
> >     at org.apache.wicket.proxy.LazyInitProxyFactory.createProxy
> >     (LazyInitProxyFactory.java:138)
> >     at
> >
> org.apache.wicket.spring.injection.annot.AnnotProxyFieldValueFactory.getFieldValue
> (AnnotProxyFieldValueFactory.java:102)
> >     at org.apache.wicket.injection.Injector.inject(Injector.java :109)
> >     at
> >     org.apache.wicket.injection.ConfigurableInjector.inject(
> ConfigurableInjector.java:40)
> >     at
> >     org.apache.wicket.injection.ComponentInjector.onInstantiation(
> ComponentInjector.java:54)
> >     at
> >     org.apache.wicket.Application.notifyComponentInstantiationListeners
> >     (Application.java:914)
> >     at org.apache.wicket.Component.<init>(Component.java:606)
> >     at org.apache.wicket.MarkupContainer.<init>(MarkupContainer.java
> :111)
> >     at org.apache.wicket.Page.<init>( Page.java:195)
> >     at org.apache.wicket.markup.html.WebPage.<init>(WebPage.java:97)
> >     at
> >     com.ptc.fusion.web.pages.FusionBasePage.<init>(FusionBasePage.java
> :18)
> >     at com.ptc.fusion.web.pages.viewer.Viewer .<init>(Viewer.java:41)
> >     at com.ptc.fusion.web.pages.viewer.Viewer$1.getPage(Viewer.java:79)
> >     at
> >     org.apache.wicket.markup.html.link.PageLink.onClick(PageLink.java
> :153)
> >     at org.apache.wicket.markup.html.link.Link.onLinkClicked
> >     (Link.java:222)
> >     at java.lang.reflect.Method.invoke(Method.java:585)
> >     at
> >     org.apache.wicket.RequestListenerInterface.invoke(
> RequestListenerInterface.java:186)
> >     at
> >
> org.apache.wicket.request.target.component.listener.ListenerInterfaceRequestTarget.processEvents
> >     (ListenerInterfaceRequestTarget.java:73)
> >     at
> >
> org.apache.wicket.request.AbstractRequestCycleProcessor.processEvents(
> AbstractRequestCycleProcessor.java:90)
> >     at org.apache.wicket.RequestCycle.processEventsAndRespond
> >     (RequestCycle.java:962)
> >     at org.apache.wicket.RequestCycle.step(RequestCycle.java:1035)
> >     at org.apache.wicket.RequestCycle.steps(RequestCycle.java:1114)
> >     at org.apache.wicket.RequestCycle.request(RequestCycle.java :474)
> >     at
> >     org.apache.wicket.protocol.http.WicketFilter.doGet(WicketFilter.java
> :248)
> >     at
> >     org.apache.wicket.protocol.http.WicketFilter.doFilter(
> WicketFilter.java:122)
> >     at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter
> >     (ServletHandler.java:1065)
> >     at
> >
> org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal
> (OpenSessionInViewFilter.java:173)
> >     at org.springframework.web.filter.OncePerRequestFilter.doFilter
> >     (OncePerRequestFilter.java:77)
> >     at
> >     org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(
> ServletHandler.java:1065)
> >     at
> >     org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java
> :365)
> >     at
> >     org.mortbay.jetty.security.SecurityHandler.handle(
> SecurityHandler.java:185)
> >     at
> >     org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java
> :181)
> >     at
> >     org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java
> >     :689)
> >     at
> >     org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java
> :391)
> >     at
> >     org.mortbay.jetty.handler.ContextHandlerCollection.handle(
> ContextHandlerCollection.java:146)
> >     at org.mortbay.jetty.handler.HandlerCollection.handle
> >     (HandlerCollection.java:114)
> >     at
> >     org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java
> :139)
> >     at org.mortbay.jetty.Server.handle(Server.java:285)
> >     at org.mortbay.jetty.HttpConnection.handleRequest
> >     (HttpConnection.java:457)
> >     at
> >     org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(
> HttpConnection.java:751)
> >     at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:500)
> >     at org.mortbay.jetty.HttpParser.parseAvailable (HttpParser.java:209)
> >     at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:357)
> >     at
> >     org.mortbay.io.nio.SelectChannelEndPoint.run(
> SelectChannelEndPoint.java:329)
> >     at org.mortbay.thread.BoundedThreadPool$PoolThread.run
> >     (BoundedThreadPool.java:475)
> >
> >     -----------------------------
> >
> >     Even though ContentSettings isn't mentioned in the stacktrace, I
> >     set a break point at the error location and to and discovered that
> >     it was indeed that class causing me problems. It's true that there
> >     is no default constructor in ContentSettings. In fact, none of my
> >     Spring managed classes have a default constructor due to my using
> >     constructor based injection.
> >
> >     The error goes away if I add an empty constructor or if I convert
> >     the ContentSettings class into a ContentSettings interface and a
> >     ContentSettingsImpl interface. I realize the latter is generally
> >     considered good form, however I may eventually have dozens of
> >     these XxxxxSettings classes are for the most part they are just
> >     wrappers to another class so they really don't benefit all that
> >     much from the Interface/Implementation pattern.
> >
> >     Does anyone know a way around this problem or am I stuck?
> >
> >     -Matt
> >
> -------------------------------------------------------------------------
> >     This SF.net email is sponsored by DB2 Express
> >     Download DB2 Express C - the FREE version of DB2 express and take
> >     control of your XML. No limits. Just data. Click to get it now.
> >     http://sourceforge.net/powerbar/db2/
> >     _______________________________________________
> >     Wicket-user mailing list
> >     Wicket-user@lists.sourceforge.net
> >     <ma...@lists.sourceforge.net>
> >     https://lists.sourceforge.net/lists/listinfo/wicket-user
> >
> >
> > ------------------------------------------------------------------------
> >
> >
> -------------------------------------------------------------------------
> > This SF.net email is sponsored by DB2 Express
> > Download DB2 Express C - the FREE version of DB2 express and take
> > control of your XML. No limits. Just data. Click to get it now.
> > http://sourceforge.net/powerbar/db2/
> > ------------------------------------------------------------------------
> >
> > _______________________________________________
> > Wicket-user mailing list
> > Wicket-user@lists.sourceforge.net
> > https://lists.sourceforge.net/lists/listinfo/wicket-user
> >
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>
>