Tag Archives: wicket

New Wicket Release: comSysto’s User Guide added

The recent release 6.13.0 of the Java web application framework Wicket brings along good news for comSysto:

An updated version of the  Wicket User Guide that comSysto’s Andrea del Bene and a team of our colleagues wrote has been added to the Wicket project’s accompanying Wicket’s new release 6.13.0.

As the Apache projects’ announcement puts it, „After many years of people asking for a reference guide for Apache Wicket we finally were able to add one to our site thanks to Andrea del Bene and comSysto for writing the guide and providing the hours of converting it to our site.“

The User Guide provides comprehensive documentation covering all the way from the framework’s basic structure and concepts to advanced topics such as complex forms, security, AJAX, or Spring integration. Its aimed at beginners as well as more experienced Wicket users.

Being users of the framework, ourselves, we’ve frequently blogged about Wicket before (see this, this, and this post)

Please give us feedback on whether you enjoy  the guide and if it’s helpful to you!

startup-feedback-1-idea

Pivot your idea – There’s no Sales like more Sales

Building an Online-Recommendation Engine with MongoDB

Once upon a time there was a Munich pizza baker who developed a technique to beam pizza out of bright sunshine. He can produce more than a thousand pizzas per second and needs a channel to sell this amount of pizza and decides to build an online shop. Mario’s initial idea is to sell pizzas, but now he is thinking about introduction of new product lines like beverages, salads and pasta. Before we take a look to the validation of Mario’s idea, let’s take a short look at the existing online shop.

Mario’s online shop is based on MongoDB, Apache Wicket and Spring. MongoDB is a document-oriented NoSQL-Database. MongoDB stores records not in tables as a relational database but in BSON documents, which is a binary version of JSON (Java Script Object Notation) and very similar to the object structure in Mario’s application. The usage of MongoDB makes his development easier and deployment faster.

Document vs. Tables

The figure shows a JSON document which is very similar to a Java object: a JSON document property with the according value corresponds to the Java object property with the appropriate value. You can add or remove properties in your Java object and this will automatically change your database schema. So there is no need to put your Java object model into a relational schema via Hibernate.

Mario also decided to build his online shop only with open-source technologies like Apache Wicket and Spring. Wicket is a very common lightweight component-based web application framework and it is closely patterned after stateful GUI frameworks such as JavaFX. The Spring Framework is an open source application framework and Inversion of Control container for the Java platform and does not impose any specific programming model. Spring has become popular in the Java community as an alternative to, replacement for, or even addition to the Enterprise JavaBean (EJB) model. Because of this architecture Mario is able to deploy its application in a lightweight application server like Tomcat or Jetty.

Pizza Application Architecture

This figure shows the system landscape of Mario. Mario has two major system on the lefthand site there is his online shop and on the righthand site there is ‘PAS’ a famous billing system. In the middle is Hadoop that connects both systems together.

In the business world an application normally does not stand alone. In most cases an application must communicate with others. The lean architecture of Marios online shop enables him to connect the billing system ‘PAS’ to his online shop. Spring for Apache Hadoop provides this integration between the two systems online shop and ‘PAS’. Hadoop supports data-intensive distributed applications and implements a computational paradigm named MapReduce, where the computation is divided into many small fragments, each of them may be executed or re-executed on any node in the cluster of commodity hardware. Mario uses Hadoop as an ETL layer that enables him to transfer gigabytes of order information into the billing system. In this case Hadoop makes it possible for a financial controller to verify if all orders were billed correctly.

In addition to the online shop feature Mario has a real-time sales dashboard that enables him to track his sales in real time. The dashboard displays daily and monthly sales statistics for each pizza and contains a map with the geographical overview of customer activity and competitor locations.

Here is a walkthrough of the shop:

Now lets talk about Mario’s incredible new idea: Mario wants to sell even more pizza! And other products as well. Mario decides to use Lean Startup methods in order to test the possible introduction of new product lines and plans an experiment to validate his new idea using a scientific approach and pure facts instead of hunches. Mario’s core assumption is that customers want to buy other products than pizza – drinks, salads and pasta. Furthermore he is worried about pricing. Mario contacts all customers to complete a survey and provides an incentive for the participation, a free pizza, to every customer who responds to the survey.

The result of the survey validated Mario’s assumption – customers want to buy beverages, salads and pasta. But he also found out that his customers are willing to pay higher prices for high-quality products and that they simply love his easy shopping flow. Currently a pizza order can be completed with three clicks only, so there is new riskiest assumption to validate: Will a more complex shopping flow affect his sales?

Validation Board

The figures shows a Validation Board. A Validation Board is a deceptively simple tool for testing out product ideas. Furthermore a validation board tracks pivots which follows from customer feedback.

Mario decides to introduce beverages, salads and pasta product lines and thinks about a possibility, how he can handle the extension of the product line without destroying the easy shopping flow. That’s why Mario thinks a recommendation engine is the right way for him. Panels for recommendations can be integrated in the online shop without changing the shopping flow. Mario hired a statistician to help him implement a recommender system for his online shop for better cross-selling. He also defined new measurement points to validate his new idea. Therefore he would like to track the conversion rate of orders as well as cross-selling rates, just as every other important event in the online shop is already tracked in realtime. So Mario can very easily perform further experiments in order to verify more assumptions.

Follow the blog to see how the story continues or come to MongoDB Usergroup Meetup in Munich, February 20, 2013 or MongoDB Days in Berlin, February 26, 2013 to get a live presentation. Our talk sheds light on how to build an online recommendation engine based on MongoDB and Apache Mahout. We’ll show which recommenders must be built to reach Mario’s goal and how these can be integrated in Mario’s shop infrastructure.

Apache Wicket – Best practices

Apache Wicket erfreut sich immer steigender Popularität und findet mehr und mehr Einsatz in Projekten. Dank der Mächtigkeit von Wicket lassen sich viele Features einfach und schnell realisieren. Für die Umsetzung dieser Features gibt es viele Wege. Dieser Artikel bietet einige Kochrezepte zum richtigen, effizienten und nachhaltigen Umgang mit Apache Wicket.

Dieser Artikel richtet sich an Entwickler, die bereits erste Erfahrungen mit Apache Wicket gesammelt haben. Entwickler, die in Wicket-Welt einsteigen tun sich oftmals schwer, weil sie Entwicklungsmethoden aus der JSF- oder Struts-Welt adaptieren. Diese Frameworks setzen vorrangig auf prozedurale Programmierung. Wicket hingegen setzt massiv auf Objektorientierung. Also vergessen Sie die Struts und JSF-Patterns, sonst werden Sie nicht lange Freude an Wicket haben.

Continue reading

Test Driven Development With Apache Wicket And Spring Framework

Since the development of our own web applications is mostly based on a Spring framework for dependency injection and application configuration in general and Apache Wicket framework as a truly component-oriented web framework for the MVC part of building a web application, it’s especially important for us to get these two frameworks running together smoothly not only when deployed on a running server instance itself but rather during the execution of our JUnit based integration tests as well. Thanks to the WicketTester API provided by the Wicket framework itself, one can easily build high-quality web applications while practicing test driven development and providing a decent set of unit and integration tests to be executed with each build. As already mentioned previously, integration and configuration of our web applications is based on a lightweight Spring container meaning that the integration of Spring’s ApplicationContext and a WicketTester API is essential to get our integration tests running. In order to best explain how to achieve that integration in an easy and elegant fashion in your integration test environment, we’ll first take a look at a configuration of these 2 framework beauties in a runtime environment.

Configuration of the runtime environment

In order to get Wicket framework up to speed when your server is up and running, you usually configure an according WicketFilter instance in your web application deployment descriptor file (web.xml) while passing it a single init parameter called applicationClassName that points to your main implementation class extending org.apache.wicket.protocol.http.WebApplication where all of your application-wide settings and initialization requirements are dealt with:

<filter>
    <filter-name>wicketfilter</filter-name>
    <filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
    <init-param>
        <param-name>applicationClassName</param-name>
        <param-value>com.comsysto.webapp.MyWebApplication</param-value>
    </init-param>
</filter>

In case you want to get Wicket application up and running while leaving the application configuration and dependency injection issues to the Spring container, the configuration to be provided within the deployment descriptor looks slightly different though:

<web-app>
    <filter>
        <filter-name>wicketfilter</filter-name>
        <filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
        <init-param>
            <param-name>applicationFactoryClassName</param-name>
            <param-value>org.apache.wicket.spring.SpringWebApplicationFactory</param-value>
        </init-param>
    </filter>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation<param-name>
        <param-value>/WEB-INF/applicationContext.xml<param-value>
    </context-param>
</web-app>

The additional configuration part containing listener and context parameter definition is a usual, purely Spring container related configuration detail. ContextLoaderListener is an implementation of standard Servlet API ServletContextListener interface provided by the Spring framework itself and is responsible for looking up an according bean definition file(s) specified by the context param above and creating an ApplicationContext instance during servlet context initialization accordingly. When integrating an ApplicationContext instance with Wicket framework, one of the beans defined in the above mentioned Spring bean definition file has to be your own specific extension of org.apache.wicket.protocol.http.WebApplication. You can either define an according bean in the bean definition file itself:

<beans>
    <bean id="myWebApp" class="com.comsysto.webapp.MyWebApplication"/>
</beans>

or use powerful classpath scanning feature of the Spring framework and annotate the MyWebApplication implementation with the appropriate @Component annotation accordingly while enabling the Spring container to scan the according package(s) of your application for relevant bean definitions:

<beans>
    <context:component-scan base-package="com.comsysto.webapp" />
    <context:component-scan base-package="com.comsysto.webapp.service" />
    <context:component-scan base-package="com.comsysto.webapp.repository" />
</beans>

Either way, if everything goes well, you’ll get a pre-configured ApplicationContext all set up during the startup of your web container. One of the beans in the ApplicationContext will be your own extension of Wicket’s WebApplication type. SpringWebApplicationFactory implementation provided by the Wicket framework itself that you have defined as the applicationFactoryClassName in the configuration of your WicketFilter will then be used in order to retrieve that very same WebApplication bean out of your Spring ApplicationContext. The Factory expects one and only one extension of Wicket’s very own WebApplication type to be found within the ApplicationContext instance at runtime. If no such bean or more than one bean extending WebApplication is found in the given ApplicationContext an according IllegalStateException will be raised and initialization of your web application will fail:

Map<? , ?> beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(ac,WebApplication.class, false, false);
if (beans.size() == 0)
{
	throw new IllegalStateException("bean of type [" + WebApplication.class.getName() +
			"] not found");
}
if (beans.size() > 1)
{
	throw new IllegalStateException("more than one bean of type [" +
			WebApplication.class.getName() + "] found, must have only one");
}

After the WebApplication bean has been successfully retrieved from the ApplicationContext via SpringWebApplicationFactory, WicketFilter will then, as part of its own initialization process, trigger both internalInit() and init() methods of the WebApplication bean. The latter one is the exact spot where the last piece of the runtime configuration puzzle between Wicket and Spring is to be placed :

@Component
public class MyWebApplication extends WebApplication {
    @Override
    protected void init() {
        addComponentInstantiationListener(new SpringComponentInjector(this));
    }

}

SpringComponentInjector provided by the Wicket framework enables you to get dependencies from the ApplicationContext directly injected into your Wicket components by simply annotating these with the according @SpringBean annotation.

Configuration of the JUnit based integration test environment

One of the main features of Apache Wicket framework is the ability to easily write and run plain unit tests for your Pages and all other kinds of Components that even include the verification of the rendering process itself by using JUnit framework and the WicketTester API only. When using Spring framework for application configuration together with Wicket, as we do, you can even use the same tools to easily write and run full blown integration tests for your web application as well. All you have to do is use Spring’s TestContext framework additionally to configure and run your JUnit based integration tests. The Spring Framework provides a set of Spring specific annotations that you can use in your integration tests in conjunction with the TestContext framework itself in order to easily configure an according ApplicationContext instance for your tests as well as for appropriate transaction management before, during and after your test execution. Following code snippet represents a simple JUnit 4 based test case using Spring’s specific annotations in order to initialize an ApplicationContext instance prior to executing the test itself:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:WEB-INF/applicationContext.xml"})
@TransactionConfiguration(transactionManager = "txManager", defaultRollback = false)
public class LoginPageTest {

    private WicketTester tester;

    @Autowired
    private ApplicationContext ctx;

    @Autowired
    private MyWebApplication myWebApplication;

    @Before
    public void setUp() {
        tester = new WicketTester(myWebApplication);
    }

    @Test
    @Transactional
    @Rollback(true)
    public void testRenderMyPage() {
        tester.startPage(LoginPage.class);
        tester.assertRenderedPage(LoginPage.class);
        tester.assertComponent("login", LoginComponent.class);
    }
}

By defining three annotations on the class level (see code snippet above) in your test, Spring’s TestContext framework takes care of preparing and initializing an ApplicationContext instance having all the beans defined in the according Spring context file as well as the transaction management in case your integration test includes some kind of database access. Fields marked with @Autowired annotation will be automatically dependency injected as well so that you can easily access and use these for your testing purposes. Since MyWebApplication, which extends Wicket’s WebApplication type and represents the main class of our web application, is also a bean within the ApplicationContext managed by Spring, it will also be provided to us by the test framework itself and can be easily used in order to initialize a WicketTester instance later on during the execution of the test’s setUp() method. With this kind of simple, annotation based test configuration we are able to run an integration test that verifies whether a LoginPage gets started and initialized, whether the rendering of the page runs smoothly and whether the page itself contains a LoginComponent that we possibly need in order to process user’s login successfully.

When you run this test though, you’ll get the following exception raised unfortunately:


java.lang.IllegalStateException: No WebApplicationContext found: no ContextLoaderListener registered?
	at org.springframework.web.context.support.WebApplicationContextUtils.getRequiredWebApplicationContext(WebApplicationContextUtils.java:84)
	at org.apache.wicket.spring.injection.annot.SpringComponentInjector.<init>(SpringComponentInjector.java:72)
	at com.comsysto.serviceplatform.uiwebapp.MyWebApplication.initializeSpringComponentInjector(MyWebApplication.java:59)
	at com.comsysto.serviceplatform.uiwebapp.MyWebApplication.init(MyWebApplication.java:49)
	at org.apache.wicket.protocol.http.WicketFilter.init(WicketFilter.java:719)
	at org.apache.wicket.protocol.http.MockWebApplication.<init>(MockWebApplication.java:168)
	at org.apache.wicket.util.tester.BaseWicketTester.<init>(BaseWicketTester.java:219)
	at org.apache.wicket.util.tester.WicketTester.<init>(WicketTester.java:325)
	at org.apache.wicket.util.tester.WicketTester.<init>(WicketTester.java:308)

As you can see above, the Exception gets raised during the initialization of the WicketTester instance even before the actual test method gets executed. Even though we have applied rather cool and simple annotation based test configuration already described and passed in perfectly well prepared ApplicationContext instance to the WicketTester instance in the constructor, somewhere down the rabbit hole someone complained that no WebApplicationContext instance could have been found which seems to be required in order to initialize the WicketTester properly.

Illegal State Sequence

Illegal State Sequence

The problem that we run against here is due to the fact that SpringComponentInjector during its own initialization is trying to get hold of an according Spring’s ApplicationContext instance that would normally be there in a runtime environment but does not find any since we are running in a test environment currently. SpringComponentInjector delegates to Spring’s own WebApplicationContextUtils class to retrieve the instance of ApplicationContext out of the ServletContext which is perfectly fine for a runtime environment but is unfortunately failing in a test environment:

public static WebApplicationContext getRequiredWebApplicationContext(ServletContext sc)
		throws IllegalStateException {

	WebApplicationContext wac = getWebApplicationContext(sc);
	if (wac == null) {
		throw new IllegalStateException("No WebApplicationContext found: no ContextLoaderListener registered?");
	}
	return wac;
}

If you still remember we defined a ContextLoaderListener in our web.xml file as part of the configuration of our runtime environment that makes sure an according WebApplicationContext instance gets initialized and registered against the ServletContext properly. Luckily, this problem can easily be solved if we slightly change the way we initialize SpringComponentInjector in our main MyWebApplication class. Apart from the constructor that we have used so far, there is another constructor in the SpringComponentInjector class that expects the caller to provide it with an according ApplicationContext instance rather than trying to resolve one on its own:

public SpringComponentInjector(WebApplication webapp, ApplicationContext ctx,
		boolean wrapInProxies)
{
	if (webapp == null)
	{
		throw new IllegalArgumentException("Argument [[webapp]] cannot be null");
	}

	if (ctx == null)
	{
		throw new IllegalArgumentException("Argument [[ctx]] cannot be null");
	}

	// store context in application's metadata ...
	webapp.setMetaData(CONTEXT_KEY, new ApplicationContextHolder(ctx));

	// ... and create and register the annotation aware injector
	InjectorHolder.setInjector(new AnnotSpringInjector(new ContextLocator(), wrapInProxies));
}

In order to use this constructor instead of the one we used previously, we now obviously need to get hold of the ApplicationContext instance on our own in our MyWebApplication implementation. The easiest way to do this is to use Spring’s own concept of lifecycle callbacks provided to the beans managed by the Spring container. Since our MyWebApplication is also a bean managed by the Spring container at runtime (enabled by the classpath scanning and @Component annotation on a type level), we can declare it to implement ApplicationContextAware interface which ensures that it gets provided with the ApplicationContext instance that it runs in by the Spring container itself during startup.

public interface ApplicationContextAware {

	void setApplicationContext(ApplicationContext applicationContext) throws BeansException;

}

So the relevant parts of MyWebApplication type will now look something like the following code snippet:

@Component
public class MyWebApplication extends WebApplication implements ApplicationContextAware {
    @Override
    protected void init() {
        addComponentInstantiationListener(new SpringComponentInjector(this, ctx, true));
    }

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.ctx = applicationContext;
    }
}

For additional clarification of how MyWebApplication now relates to both Wicket and Spring framework here is an according class diagram:

MyWebApplication class diagram

MyWebApplication Class Diagram

And that’s all folks! No additional modifications are required to the test itself. It’s gonna turn green now. This way you can use exactly the same Spring context configuration that you’d use in your runtime environment for running your JUnit based integration tests as well. Just grab the colleague you like most and try a pair programming and test first approach with Wicket and Spring. You’ll be delighted! And if you’re not, go buy yourself one of these ;).