I am building a Wicket web application which is going to have to handle a lot of simultaneous requests. I've setup a test environment and some jmeter scripts to do load testing and I notice I can reduce the CPU and memory footprint of my application if I make most pages Stateless.
I've added code to the onBeforeRender() method of the biggest page to show me which of the components are causing my page to be stateful. This is the code I have for detecting that:
@Override
protected void onBeforeRender() {
if (!getSession().isTemporary()) {
visitChildren(Component.class, new IVisitor<Component>() {
@Override
public Object component(Component component) {
String pageClassName = AbstractStatelessBasePage.this.getClass().getName();
if (!component.isStateless()) {
String msg = pageClassName+" is stateful because of stateful component " + component.getClass().getName() + " with id " + component.getId() + ".";
List<IBehavior> behaviourList = component.getBehaviors();
for (IBehavior iBehavior : behaviourList) {
if (!iBehavior.getStatelessHint(component)) {
msg += "\n\t" + "The component has stateful behaviour: " + iBehavior.getClass().getName();
}
}
LOG.error(msg);
}
checkedPages.add(pageClassName);
return CONTINUE_TRAVERSAL;
}
});
}
}
In the output I see that the stateful behavior is caused by AjaxLinks used by some of the existing components in the pages:
ERROR - AbstractStatelessBasePage$1.component(45) | HomePage is stateful because of stateful component InfoGrid$InfoButton with id infoButton.
The component has stateful behaviour: org.apache.wicket.ajax.markup.html.AjaxLink$1
I have tried to add getStatelessHint() methods returning "true" in a few places, but it doesn's seem to help. I've also checked the Wicket source code of AjaxLink, its superclasses and some surrounding code, but I can't seem to discover why AjaxLink needs to be stateful in all cases.
In my case, the AjaxLink is in an otherwise Stateless page and the link does not store state. How can I make Wicket understand that this AjaxLink can be stateless?
Thanks for your help, Rolf
Edit: Accepted answer works with Wicket 1.4.19.
Added the following to the maven pom.xml:
<dependency>
<groupId>com.jolira</groupId>
<artifactId>wicket-stateless</artifactId>
<version>1.0.8</version>
</dependency>
Changed all components which extended "AjaxLink" to extend "StatelessAjaxFallbackLink".
Don't forget to add the following to your WicketApplication class, it will save you some troubleshooting time:
@Override
protected IRequestCycleProcessor newRequestCycleProcessor() {
return new StatelessWebRequestCycleProcessor();
}
Please note that StatelessForm and other stateless stuff does not work from within a repeater (like "ListView") for some reason.