You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@wicket.apache.org by Tom John <to...@gmail.com> on 2008/02/22 06:18:36 UTC

Accessing prototype scoped panel beans using @SpringBean annotation

Hi,

First of all let me apologise for the length of this post, I thought I
should include too much info rather than too little.

I'm using wicket-1.3.1, Spring 2.5.1 on JDK1.5 and Jetty6.1.6.  My goal is
to define 1..n Panels in my Spring application context then access them from
within a test page using @SpringBean annotations.

applicationContext.xml contains:

    <bean id="testPanel1" class="com.fastsearch.admomentum.server.TestPanel"
scope="prototype">
        <constructor-arg value="testPanelOne"/>
    </bean>

TestPage class is as follows:

public class TestPage extends WebPage {

    @SpringBean(name="testPanel1")
    private TestPanel testPanel1;

    public TestPage() {
        add(testPanel1);
    }
}

And TestPanel class is as follows:

public class TestPanel extends Panel implements ITestPanel {

    private TestForm form;

    public TestPanel(String id) {
        super(id);

        form = new TestForm("testForm");
        form.setTestFormField("oranges");
        add(form);
    }

    private class TestForm extends Form {
        private String testFormField;

        public TestForm(String id) {
            super(id);
            add(new TextField("testFormField", new PropertyModel(this,
"testFormField")));
        }

        protected void onSubmit() {
            PageParameters params = new PageParameters();
            params.add("testFormField", testFormField);
        }

        public void setTestFormField(String testFormField) {
            this.testFormField = testFormField;
        }
    }
}

So, the problem is that when I hit http://localhost:8080/ the
"add(testPanel1);" line in the constructor for TestPage causes the following
exception to be thrown:

-----------------------------------
WicketMessage: Error attaching this container for rendering: [Page class =
com.fastsearch.admomentum.server.TestPage, id = 0, version = 0]

Root cause:

java.lang.IllegalArgumentException: Protected method: onBeforeRender()V
at net.sf.cglib.proxy.MethodProxy$1.invoke(MethodProxy.java:55)
at
org.apache.wicket.proxy.LazyInitProxyFactory$CGLibInterceptor.intercept(LazyInitProxyFactory.java:318)
at
WICKET_com.fastsearch.admomentum.server.TestPanel$$EnhancerByCGLIB$$504480a9.onBeforeRender(<generated>)
at org.apache.wicket.Component.internalBeforeRender(Component.java:995)
at org.apache.wicket.Component.beforeRender(Component.java:1027)
at
org.apache.wicket.MarkupContainer.onBeforeRenderChildren(MarkupContainer.java:1513)
at org.apache.wicket.Component.onBeforeRender(Component.java:3657)
at org.apache.wicket.Page.onBeforeRender(Page.java:1402)
at org.apache.wicket.Component.internalBeforeRender(Component.java:995)
at org.apache.wicket.Component.beforeRender(Component.java:1027)
at org.apache.wicket.Component.prepareForRender(Component.java:2139)
at org.apache.wicket.Page.renderPage(Page.java:870)
at
org.apache.wicket.request.target.component.BookmarkablePageRequestTarget.respond(BookmarkablePageRequestTarget.java:231)
at
org.apache.wicket.request.AbstractRequestCycleProcessor.respond(AbstractRequestCycleProcessor.java:103)
at
org.apache.wicket.RequestCycle.processEventsAndRespond(RequestCycle.java:1172)
at org.apache.wicket.RequestCycle.step(RequestCycle.java:1241)
at org.apache.wicket.RequestCycle.steps(RequestCycle.java:1316)
at org.apache.wicket.RequestCycle.request(RequestCycle.java:493)
at org.apache.wicket.protocol.http.WicketFilter.doGet(WicketFilter.java:354)
at
org.apache.wicket.protocol.http.WicketServlet.doGet(WicketServlet.java:121)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:367)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:712)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:139)
at org.mortbay.jetty.Server.handle(Server.java:295)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:503)
at
org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:827)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:511)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:210)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:379)
at
org.mortbay.jetty.bio.SocketConnector$Connection.run(SocketConnector.java:226)
at
org.mortbay.thread.BoundedThreadPool$PoolThread.run(BoundedThreadPool.java:442)

Complete stack:

org.apache.wicket.WicketRuntimeException: Error attaching this container for
rendering: [Page class = com.fastsearch.admomentum.server.TestPage, id = 0,
version = 0]
at
org.apache.wicket.MarkupContainer.onBeforeRenderChildren(MarkupContainer.java:1525)
at org.apache.wicket.Component.onBeforeRender(Component.java:3657)
at org.apache.wicket.Page.onBeforeRender(Page.java:1402)
at org.apache.wicket.Component.internalBeforeRender(Component.java:995)
at org.apache.wicket.Component.beforeRender(Component.java:1027)
at org.apache.wicket.Component.prepareForRender(Component.java:2139)
at org.apache.wicket.Page.renderPage(Page.java:870)
at
org.apache.wicket.request.target.component.BookmarkablePageRequestTarget.respond(BookmarkablePageRequestTarget.java:231)
at
org.apache.wicket.request.AbstractRequestCycleProcessor.respond(AbstractRequestCycleProcessor.java:103)
at
org.apache.wicket.RequestCycle.processEventsAndRespond(RequestCycle.java:1172)
at org.apache.wicket.RequestCycle.step(RequestCycle.java:1241)
at org.apache.wicket.RequestCycle.steps(RequestCycle.java:1316)
at org.apache.wicket.RequestCycle.request(RequestCycle.java:493)
at org.apache.wicket.protocol.http.WicketFilter.doGet(WicketFilter.java:354)
-----------------------------------


Based on this stack trace I tried overriding onBeforeRender() in TestPanel
and changing it's scope to public ... just to see what would happen:

    public void onBeforeRender() {
        super.onBeforeRender();
    }

but that then caused the following exception to be thrown which claims
"Something in the hierarchy of
WICKET_com.fastsearch.admomentum.server.test.TestPanel$$EnhancerByCGLIB$$11ed548f
has not called super.onBeforeRender() in the override of onBeforeRender()
method", which is clearly not the case.


-----------------------------------
WicketMessage: Error attaching this container for rendering: [Page class =
com.fastsearch.admomentum.server.test.TestPage, id = 0, version = 0]

Root cause:

java.lang.IllegalStateException: org.apache.wicket.Component has not been
properly rendered. Something in the hierarchy of
WICKET_com.fastsearch.admomentum.server.test.TestPanel$$EnhancerByCGLIB$$11ed548f
has not called super.onBeforeRender() in the override of onBeforeRender()
method
at org.apache.wicket.Component.internalBeforeRender(Component.java:999)
at org.apache.wicket.Component.beforeRender(Component.java:1027)
at
org.apache.wicket.MarkupContainer.onBeforeRenderChildren(MarkupContainer.java:1513)
at org.apache.wicket.Component.onBeforeRender(Component.java:3657)
at org.apache.wicket.Page.onBeforeRender(Page.java:1402)
at org.apache.wicket.Component.internalBeforeRender(Component.java:995)
at org.apache.wicket.Component.beforeRender(Component.java:1027)
at org.apache.wicket.Component.prepareForRender(Component.java:2139)
at org.apache.wicket.Page.renderPage(Page.java:870)
at
org.apache.wicket.request.target.component.BookmarkablePageRequestTarget.respond(BookmarkablePageRequestTarget.java:231)
at
org.apache.wicket.request.AbstractRequestCycleProcessor.respond(AbstractRequestCycleProcessor.java:103)
at
org.apache.wicket.RequestCycle.processEventsAndRespond(RequestCycle.java:1172)
at org.apache.wicket.RequestCycle.step(RequestCycle.java:1241)
at org.apache.wicket.RequestCycle.steps(RequestCycle.java:1316)
at org.apache.wicket.RequestCycle.request(RequestCycle.java:493)
at org.apache.wicket.protocol.http.WicketFilter.doGet(WicketFilter.java:354)
at
org.apache.wicket.protocol.http.WicketServlet.doGet(WicketServlet.java:121)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:367)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:712)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:139)
at org.mortbay.jetty.Server.handle(Server.java:295)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:503)
at
org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:827)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:511)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:210)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:379)
at
org.mortbay.jetty.bio.SocketConnector$Connection.run(SocketConnector.java:226)
at
org.mortbay.thread.BoundedThreadPool$PoolThread.run(BoundedThreadPool.java:442)

Complete stack:

org.apache.wicket.WicketRuntimeException: Error attaching this container for
rendering: [Page class = com.fastsearch.admomentum.server.test.TestPage, id
= 0, version = 0]
at
org.apache.wicket.MarkupContainer.onBeforeRenderChildren(MarkupContainer.java:1525)
at org.apache.wicket.Component.onBeforeRender(Component.java:3657)
at org.apache.wicket.Page.onBeforeRender(Page.java:1402)
at org.apache.wicket.Component.internalBeforeRender(Component.java:995)
at org.apache.wicket.Component.beforeRender(Component.java:1027)
at org.apache.wicket.Component.prepareForRender(Component.java:2139)
at org.apache.wicket.Page.renderPage(Page.java:870)
at
org.apache.wicket.request.target.component.BookmarkablePageRequestTarget.respond(BookmarkablePageRequestTarget.java:231)
at
org.apache.wicket.request.AbstractRequestCycleProcessor.respond(AbstractRequestCycleProcessor.java:103)
at
org.apache.wicket.RequestCycle.processEventsAndRespond(RequestCycle.java:1172)
at org.apache.wicket.RequestCycle.step(RequestCycle.java:1241)
at org.apache.wicket.RequestCycle.steps(RequestCycle.java:1316)
at org.apache.wicket.RequestCycle.request(RequestCycle.java:493)
at org.apache.wicket.protocol.http.WicketFilter.doGet(WicketFilter.java:354)
-----------------------------------


Can anyone throw some light on what I'm doing wrong.  I'm not tied to the
idea of the Panels being prototype beans however without it, immediately on
server startup, I get a "WicketRuntimeException: There is no application
attached to current thread main".  Making them prototype seems to be the
only way for me to get my server to startup cleanly.

Thanks,
Tom.
-- 
View this message in context: http://www.nabble.com/Accessing-prototype-scoped-panel-beans-using-%40SpringBean-annotation-tp15627974p15627974.html
Sent from the Wicket - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: Accessing prototype scoped panel beans using @SpringBean annotation

Posted by Igor Vaynberg <ig...@gmail.com>.
this panel factory is what i have done in the past also. although i
simply had a generic IComponentFactory { Component newComponent(String
id); } which seemed to work for most cases.

the problem with injecting panels like that directly is that wicket
_has to_ proxy these injected values. There are a couple of ways
around this:

a) we can check if the object is a subclass of Component and choose not to proxy
b) we can add a proxy attribute to @SpringBean that can be set to false

feel free to add these as an rfe, but i think the component factory is
a good solution.

-igor


On Fri, Feb 22, 2008 at 5:01 AM, Ned Collyer <ne...@gmail.com> wrote:
>
>
>  Stefan Fußenegger wrote:
>  >
>  > Hi Tom,
>  >
>  > I'd suggest not to use Spring to manage panels. You should rather create a
>  > new panel for every page and request. You should use Spring to manage your
>  > services and inject those into your panels.
>  >
>  > Best regards, Stefan
>  >
>
>  Hi Stephan :) (I work with Tom)
>
>  We have a work around for this specific problem, and it still involves
>  spring, but not using panels directly.
>
>  Basically the situation is as follows.
>
>  We have a main wicket project which is published as a jar.
>
>  There are also other modules also published as "plugin" jars.
>
>  We launch these with an embedded jetty instance.
>
>  The problem is the Main project contains the page instances, and the other
>  jars contain the panels.
>
>  The Main project has no idea about which panels are available, as these will
>  be determined at run time by whatever has been configured (thru spring).
>  The main jar has no knowledge of which panel classes exist - so we cannot
>  really instantiate new ones using plain old java.
>
>  There are a few ways to approach this, ie, having some class loader which
>  resolves given string "class references", and those strings are wired in
>  through spring.  This works - but feels a bit hacky.
>
>  Our workaround is .. somewhat similar - we basically have a panel factory in
>  the plugin that instantiate a panel and return it.  We can then wire these
>  panel factories thru spring to a given page.
>
>  This turns out to be quite elegant - however it would be nice if we had the
>  ability to wire "plugin" panels to the main jar directly without this
>  factory.
>
>  Rgds
>
>  Ned
>  --
>  View this message in context: http://www.nabble.com/Accessing-prototype-scoped-panel-beans-using-%40SpringBean-annotation-tp15627974p15632893.html
>
>
> Sent from the Wicket - User mailing list archive at Nabble.com.
>
>
>  ---------------------------------------------------------------------
>  To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
>  For additional commands, e-mail: users-help@wicket.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: Accessing prototype scoped panel beans using @SpringBean annotation

Posted by Stefan Fußenegger <st...@gmx.at>.
What do you mean by "directly"? Do you want to inject the panels rather than
the factories? You could probably try to write your own annotation and use a
custom org.apache.wicket.injection.IFieldValueFactory



Ned Collyer wrote:
> 
> 
> Stefan Fußenegger wrote:
>> 
>> Hi Tom,
>> 
>> I'd suggest not to use Spring to manage panels. You should rather create
>> a new panel for every page and request. You should use Spring to manage
>> your services and inject those into your panels.
>> 
>> Best regards, Stefan
>> 
> 
> Hi Stephan :) (I work with Tom)
> 
> We have a work around for this specific problem, and it still involves
> spring, but not using panels directly.
> 
> Basically the situation is as follows.
> 
> We have a main wicket project which is published as a jar.
> 
> There are also other modules also published as "plugin" jars.
> 
> We launch these with an embedded jetty instance.
> 
> The problem is the Main project contains the page instances, and the other
> jars contain the panels.
> 
> The Main project has no idea about which panels are available, as these
> will be determined at run time by whatever has been configured (thru
> spring).  The main jar has no knowledge of which panel classes exist - so
> we cannot really instantiate new ones using plain old java.
> 
> There are a few ways to approach this, ie, having some class loader which
> resolves given string "class references", and those strings are wired in
> through spring.  This works - but feels a bit hacky.
> 
> Our workaround is .. somewhat similar - we basically have a panel factory
> in the plugin that instantiate a panel and return it.  We can then wire
> these panel factories thru spring to a given page.
> 
> This turns out to be quite elegant - however it would be nice if we had
> the ability to wire "plugin" panels to the main jar directly without this
> factory.
> 
> Rgds
> 
> Ned
> 


-----
-------
Stefan Fußenegger
http://talk-on-tech.blogspot.com // looking for a nicer domain ;)
-- 
View this message in context: http://www.nabble.com/Accessing-prototype-scoped-panel-beans-using-%40SpringBean-annotation-tp15627974p15632905.html
Sent from the Wicket - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: Accessing prototype scoped panel beans using @SpringBean annotation

Posted by James Carman <ja...@carmanconsulting.com>.
The big question here is why do you want to use Spring to
configure/construct your panels?  What is the use case?

On 2/23/08, Kent Tong <ke...@cpttm.org.mo> wrote:
>
>
>  Ned Collyer wrote:
>  >
>  > There are a few ways to approach this, ie, having some class loader which
>  > resolves given string "class references", and those strings are wired in
>  > through spring.  This works - but feels a bit hacky.
>  >
>
>
> I don't know why you feel this hacky. It looks clean and easy to me:
>
>
>  public class TestPage extends WebPage {
>
>         @SpringBean(name = "config")
>         private Config config;
>
>         public TestPage() {
>                 add(PanelFactory.getPanel(config, "testPanelOne"));
>         }
>  }
>
>  public class PanelFactory {
>         public static Panel getPanel(Config config, String id) {
>                 Class<? extends Panel> c =
>  Class.forName(config.getPanelClass()).asSubclass(Panel.class);
>                 Constructor<? extends Panel> constructor = c.getConstructor(String.class);
>                 return constructor.newInstance(id);
>         }
>  }
>
>
>
>  -----
>  --
>  Kent Tong
>  Wicket tutorials freely available at http://www.agileskills2.org/EWDW
>  Axis2 tutorials freely available at http://www.agileskills2.org/DWSAA
>
> --
>  View this message in context: http://www.nabble.com/Accessing-prototype-scoped-panel-beans-using-%40SpringBean-annotation-tp15627974p15648766.html
>
> Sent from the Wicket - User mailing list archive at Nabble.com.
>
>
>  ---------------------------------------------------------------------
>  To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
>  For additional commands, e-mail: users-help@wicket.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: Accessing prototype scoped panel beans using @SpringBean annotation

Posted by Ned Collyer <ne...@gmail.com>.
This is close to the solution we are currently using ;)

Thanks for the info on the Classes object.

Rgds

Ned


Kent Tong wrote:
> 
> 
> public class TestPage extends WebPage {
> 	@SpringBean(name = "panelFactory")
> 	private PanelFactory panelFactory;
> 
> 	public TestPage() {
> 		add(panelFactory.getPanel("testPanelOne"));
> 	}
> 
> }
> 	<bean id="config" class="myapp.Config" scope="singleton">
> 		<property name="panelClass">
> 			<value>myapp.TestPanel</value>
> 		</property>
> 	</bean>
> 	<bean id="panelFactory" class="myapp.PanelFactory" scope="singleton">
> 		<property name="config" ref="config"/>
> 	</bean>
> 
> 

-- 
View this message in context: http://www.nabble.com/Accessing-prototype-scoped-panel-beans-using-%40SpringBean-annotation-tp15627974p15657435.html
Sent from the Wicket - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: Accessing prototype scoped panel beans using @SpringBean annotation

Posted by Kent Tong <ke...@cpttm.org.mo>.

Ned Collyer wrote:
> 
> Spring is meant to be the factory :).  Isn't that a big part of why we use
> Spring?
> 
> Incidently there is a Classes class that has some handy "cached" stuff for
> resolving class references.
> see org.apache.wicket.util.lang.Classes
> 

You can certain make the PanelFactory a spring bean:

public class TestPage extends WebPage {
	@SpringBean(name = "panelFactory")
	private PanelFactory panelFactory;

	public TestPage() {
		add(panelFactory.getPanel("testPanelOne"));
	}

}
	<bean id="config" class="myapp.Config" scope="singleton">
		<property name="panelClass">
			<value>myapp.TestPanel</value>
		</property>
	</bean>
	<bean id="panelFactory" class="myapp.PanelFactory" scope="singleton">
		<property name="config" ref="config"/>
	</bean>


The Wicket Classes class is not meant for performance. Normal classloaders
probable 
provide better caching support. It was introduced to fix concurrency
problems.


-----
--
Kent Tong
Wicket tutorials freely available at http://www.agileskills2.org/EWDW
Axis2 tutorials freely available at http://www.agileskills2.org/DWSAA
-- 
View this message in context: http://www.nabble.com/Accessing-prototype-scoped-panel-beans-using-%40SpringBean-annotation-tp15627974p15651407.html
Sent from the Wicket - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: Accessing prototype scoped panel beans using @SpringBean annotation

Posted by Ned Collyer <ne...@gmail.com>.

Kent Tong wrote:
> 
> I don't know why you feel this hacky. It looks clean and easy to me:
> 

It works, and the implementation is nice and easy BUT...

Spring is meant to be the factory :).  Isn't that a big part of why we use
spring?
-- 
View this message in context: http://www.nabble.com/Accessing-prototype-scoped-panel-beans-using-%40SpringBean-annotation-tp15627974p15651187.html
Sent from the Wicket - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: Accessing prototype scoped panel beans using @SpringBean annotation

Posted by Kent Tong <ke...@cpttm.org.mo>.

Ned Collyer wrote:
> 
> There are a few ways to approach this, ie, having some class loader which
> resolves given string "class references", and those strings are wired in
> through spring.  This works - but feels a bit hacky.
> 

I don't know why you feel this hacky. It looks clean and easy to me:

public class TestPage extends WebPage {
	@SpringBean(name = "config")
	private Config config;

	public TestPage() {
		add(PanelFactory.getPanel(config, "testPanelOne"));
	}
}

public class PanelFactory {
	public static Panel getPanel(Config config, String id) {
		Class<? extends Panel> c =
Class.forName(config.getPanelClass()).asSubclass(Panel.class);
		Constructor<? extends Panel> constructor = c.getConstructor(String.class);
		return constructor.newInstance(id);
	}
}



-----
--
Kent Tong
Wicket tutorials freely available at http://www.agileskills2.org/EWDW
Axis2 tutorials freely available at http://www.agileskills2.org/DWSAA
-- 
View this message in context: http://www.nabble.com/Accessing-prototype-scoped-panel-beans-using-%40SpringBean-annotation-tp15627974p15648766.html
Sent from the Wicket - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: Accessing prototype scoped panel beans using @SpringBean annotation

Posted by Ned Collyer <ne...@gmail.com>.

Stefan Fußenegger wrote:
> 
> Hi Tom,
> 
> I'd suggest not to use Spring to manage panels. You should rather create a
> new panel for every page and request. You should use Spring to manage your
> services and inject those into your panels.
> 
> Best regards, Stefan
> 

Hi Stephan :) (I work with Tom)

We have a work around for this specific problem, and it still involves
spring, but not using panels directly.

Basically the situation is as follows.

We have a main wicket project which is published as a jar.

There are also other modules also published as "plugin" jars.

We launch these with an embedded jetty instance.

The problem is the Main project contains the page instances, and the other
jars contain the panels.

The Main project has no idea about which panels are available, as these will
be determined at run time by whatever has been configured (thru spring). 
The main jar has no knowledge of which panel classes exist - so we cannot
really instantiate new ones using plain old java.

There are a few ways to approach this, ie, having some class loader which
resolves given string "class references", and those strings are wired in
through spring.  This works - but feels a bit hacky.

Our workaround is .. somewhat similar - we basically have a panel factory in
the plugin that instantiate a panel and return it.  We can then wire these
panel factories thru spring to a given page.

This turns out to be quite elegant - however it would be nice if we had the
ability to wire "plugin" panels to the main jar directly without this
factory.

Rgds

Ned
-- 
View this message in context: http://www.nabble.com/Accessing-prototype-scoped-panel-beans-using-%40SpringBean-annotation-tp15627974p15632893.html
Sent from the Wicket - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: Accessing prototype scoped panel beans using @SpringBean annotation

Posted by Stefan Fußenegger <st...@gmx.at>.
Hi Tom,

I'd suggest not to use Spring to manage panels. You should rather create a
new panel for every page and request. You should use Spring to manage your
services and inject those into your panels.

Best regards, Stefan



Tom John wrote:
> 
> Hi,
> 
> First of all let me apologise for the length of this post, I thought I
> should include too much info rather than too little.
> 
> I'm using wicket-1.3.1, Spring 2.5.1 on JDK1.5 and Jetty6.1.6.  My goal is
> to define 1..n Panels in my Spring application context then access them
> from within a test page using @SpringBean annotations.
> 
> applicationContext.xml contains:
> 
>     <bean id="testPanel1" class="com.example.TestPanel" scope="prototype">
>         <constructor-arg value="testPanelOne"/>
>     </bean>
> 
> TestPage class is as follows:
> 
> 
> public class TestPage extends WebPage {
> 
>     @SpringBean(name="testPanel1")
>     private TestPanel testPanel1;
> 
>     public TestPage() {
>         add(testPanel1);
>     }
> }
> 
> 
> And TestPanel class is as follows:
> 
> 
> public class TestPanel extends Panel implements ITestPanel {
> 
>     private TestForm form;
> 
>     public TestPanel(String id) {
>         super(id);
> 
>         form = new TestForm("testForm");
>         form.setTestFormField("oranges");
>         add(form);
>     }
> 
>     private class TestForm extends Form {
>         private String testFormField;
> 
>         public TestForm(String id) {
>             super(id);
>             add(new TextField("testFormField", new PropertyModel(this,
> "testFormField")));
>         }
> 
>         protected void onSubmit() {
>             PageParameters params = new PageParameters();
>             params.add("testFormField", testFormField);
>         }
> 
>         public void setTestFormField(String testFormField) {
>             this.testFormField = testFormField;
>         }
>     }
> }
> 
> 
> So, the problem is that when I hit http://localhost:8080/ the
> "add(testPanel1);" line in the constructor for TestPage causes the
> following exception to be thrown:
> 
> 
> WicketMessage: Error attaching this container for rendering: [Page class =
> com.example.TestPage, id = 0, version = 0]
> 
> Root cause:
> 
> java.lang.IllegalArgumentException: Protected method: onBeforeRender()V
> at net.sf.cglib.proxy.MethodProxy$1.invoke(MethodProxy.java:55)
> at
> org.apache.wicket.proxy.LazyInitProxyFactory$CGLibInterceptor.intercept(LazyInitProxyFactory.java:318)
> at
> WICKET_com.example.TestPanel$$EnhancerByCGLIB$$504480a9.onBeforeRender(<generated>)
> at org.apache.wicket.Component.internalBeforeRender(Component.java:995)
> at org.apache.wicket.Component.beforeRender(Component.java:1027)
> at
> org.apache.wicket.MarkupContainer.onBeforeRenderChildren(MarkupContainer.java:1513)
> at org.apache.wicket.Component.onBeforeRender(Component.java:3657)
> at org.apache.wicket.Page.onBeforeRender(Page.java:1402)
> at org.apache.wicket.Component.internalBeforeRender(Component.java:995)
> at org.apache.wicket.Component.beforeRender(Component.java:1027)
> at org.apache.wicket.Component.prepareForRender(Component.java:2139)
> at org.apache.wicket.Page.renderPage(Page.java:870)
> at
> org.apache.wicket.request.target.component.BookmarkablePageRequestTarget.respond(BookmarkablePageRequestTarget.java:231)
> at
> org.apache.wicket.request.AbstractRequestCycleProcessor.respond(AbstractRequestCycleProcessor.java:103)
> at
> org.apache.wicket.RequestCycle.processEventsAndRespond(RequestCycle.java:1172)
> at org.apache.wicket.RequestCycle.step(RequestCycle.java:1241)
> at org.apache.wicket.RequestCycle.steps(RequestCycle.java:1316)
> at org.apache.wicket.RequestCycle.request(RequestCycle.java:493)
> at
> org.apache.wicket.protocol.http.WicketFilter.doGet(WicketFilter.java:354)
> at
> org.apache.wicket.protocol.http.WicketServlet.doGet(WicketServlet.java:121)
> at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
> at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
> at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
> at
> org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:367)
> at
> org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
> at
> org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:712)
> at
> org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:139)
> at org.mortbay.jetty.Server.handle(Server.java:295)
> at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:503)
> at
> org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:827)
> at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:511)
> at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:210)
> at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:379)
> at
> org.mortbay.jetty.bio.SocketConnector$Connection.run(SocketConnector.java:226)
> at
> org.mortbay.thread.BoundedThreadPool$PoolThread.run(BoundedThreadPool.java:442)
> 
> Complete stack:
> 
> org.apache.wicket.WicketRuntimeException: Error attaching this container
> for rendering: [Page class = com.example.TestPage, id = 0, version = 0]
> at
> org.apache.wicket.MarkupContainer.onBeforeRenderChildren(MarkupContainer.java:1525)
> at org.apache.wicket.Component.onBeforeRender(Component.java:3657)
> at org.apache.wicket.Page.onBeforeRender(Page.java:1402)
> at org.apache.wicket.Component.internalBeforeRender(Component.java:995)
> at org.apache.wicket.Component.beforeRender(Component.java:1027)
> at org.apache.wicket.Component.prepareForRender(Component.java:2139)
> at org.apache.wicket.Page.renderPage(Page.java:870)
> at
> org.apache.wicket.request.target.component.BookmarkablePageRequestTarget.respond(BookmarkablePageRequestTarget.java:231)
> at
> org.apache.wicket.request.AbstractRequestCycleProcessor.respond(AbstractRequestCycleProcessor.java:103)
> at
> org.apache.wicket.RequestCycle.processEventsAndRespond(RequestCycle.java:1172)
> at org.apache.wicket.RequestCycle.step(RequestCycle.java:1241)
> at org.apache.wicket.RequestCycle.steps(RequestCycle.java:1316)
> at org.apache.wicket.RequestCycle.request(RequestCycle.java:493)
> at
> org.apache.wicket.protocol.http.WicketFilter.doGet(WicketFilter.java:354)
> 
> 
> Based on this stack trace I tried overriding onBeforeRender() in TestPanel
> and changing it's scope to public ... just to see what would happen:
> 
>     public void onBeforeRender() {
>         super.onBeforeRender();
>     }
> 
> but that then caused the following exception to be thrown which claims
> "Something in the hierarchy of
> WICKET_com.example.TestPanel$$EnhancerByCGLIB$$11ed548f has not called
> super.onBeforeRender() in the override of onBeforeRender() method", which
> is clearly not the case.
> 
> 
> WicketMessage: Error attaching this container for rendering: [Page class =
> com.example.TestPage, id = 0, version = 0]
> 
> Root cause:
> 
> java.lang.IllegalStateException: org.apache.wicket.Component has not been
> properly rendered. Something in the hierarchy of
> WICKET_com.example.TestPanel$$EnhancerByCGLIB$$11ed548f has not called
> super.onBeforeRender() in the override of onBeforeRender() method
> at org.apache.wicket.Component.internalBeforeRender(Component.java:999)
> at org.apache.wicket.Component.beforeRender(Component.java:1027)
> at
> org.apache.wicket.MarkupContainer.onBeforeRenderChildren(MarkupContainer.java:1513)
> at org.apache.wicket.Component.onBeforeRender(Component.java:3657)
> at org.apache.wicket.Page.onBeforeRender(Page.java:1402)
> at org.apache.wicket.Component.internalBeforeRender(Component.java:995)
> at org.apache.wicket.Component.beforeRender(Component.java:1027)
> at org.apache.wicket.Component.prepareForRender(Component.java:2139)
> at org.apache.wicket.Page.renderPage(Page.java:870)
> at
> org.apache.wicket.request.target.component.BookmarkablePageRequestTarget.respond(BookmarkablePageRequestTarget.java:231)
> at
> org.apache.wicket.request.AbstractRequestCycleProcessor.respond(AbstractRequestCycleProcessor.java:103)
> at
> org.apache.wicket.RequestCycle.processEventsAndRespond(RequestCycle.java:1172)
> at org.apache.wicket.RequestCycle.step(RequestCycle.java:1241)
> at org.apache.wicket.RequestCycle.steps(RequestCycle.java:1316)
> at org.apache.wicket.RequestCycle.request(RequestCycle.java:493)
> at
> org.apache.wicket.protocol.http.WicketFilter.doGet(WicketFilter.java:354)
> at
> org.apache.wicket.protocol.http.WicketServlet.doGet(WicketServlet.java:121)
> at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
> at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
> at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
> at
> org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:367)
> at
> org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
> at
> org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:712)
> at
> org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:139)
> at org.mortbay.jetty.Server.handle(Server.java:295)
> at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:503)
> at
> org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:827)
> at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:511)
> at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:210)
> at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:379)
> at
> org.mortbay.jetty.bio.SocketConnector$Connection.run(SocketConnector.java:226)
> at
> org.mortbay.thread.BoundedThreadPool$PoolThread.run(BoundedThreadPool.java:442)
> 
> Complete stack:
> 
> org.apache.wicket.WicketRuntimeException: Error attaching this container
> for rendering: [Page class = com.example.TestPage, id = 0, version = 0]
> at
> org.apache.wicket.MarkupContainer.onBeforeRenderChildren(MarkupContainer.java:1525)
> at org.apache.wicket.Component.onBeforeRender(Component.java:3657)
> at org.apache.wicket.Page.onBeforeRender(Page.java:1402)
> at org.apache.wicket.Component.internalBeforeRender(Component.java:995)
> at org.apache.wicket.Component.beforeRender(Component.java:1027)
> at org.apache.wicket.Component.prepareForRender(Component.java:2139)
> at org.apache.wicket.Page.renderPage(Page.java:870)
> at
> org.apache.wicket.request.target.component.BookmarkablePageRequestTarget.respond(BookmarkablePageRequestTarget.java:231)
> at
> org.apache.wicket.request.AbstractRequestCycleProcessor.respond(AbstractRequestCycleProcessor.java:103)
> at
> org.apache.wicket.RequestCycle.processEventsAndRespond(RequestCycle.java:1172)
> at org.apache.wicket.RequestCycle.step(RequestCycle.java:1241)
> at org.apache.wicket.RequestCycle.steps(RequestCycle.java:1316)
> at org.apache.wicket.RequestCycle.request(RequestCycle.java:493)
> at
> org.apache.wicket.protocol.http.WicketFilter.doGet(WicketFilter.java:354)
> 
> 
> Can anyone throw some light on what I'm doing wrong.  I'm not tied to the
> idea of the Panels being prototype beans however without it, immediately
> on server startup, I get a "WicketRuntimeException: There is no
> application attached to current thread main".  Making them prototype seems
> to be the only way for me to get my server to startup cleanly.
> 
> Thanks,
> Tom.
> 


-----
-------
Stefan Fußenegger
http://talk-on-tech.blogspot.com // looking for a nicer domain ;)
-- 
View this message in context: http://www.nabble.com/Accessing-prototype-scoped-panel-beans-using-%40SpringBean-annotation-tp15627974p15631515.html
Sent from the Wicket - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org