22 October 2010

Getting started with Vaadin

A couple of weeks ago I made myself a promise that I would look into a new technology every month and write something about it here. I've been looking around for technologies unknown to me and perhaps to some of you, so I will start out with a RIA framework called Vaadin.


About Vaadin


Before I started my journey with Vaadin, I have to say that I had never heard of it before. I was quite surprised that they were at version 6.4.6 already. That must mean something right? Let's find out.
My first impression is that for an open source framework their documentation is excellent. It's something you don't see everyday with open source frameworks and I've seen quite a few over the past years.
Vaadin really impressed with that and there even is a free (e-)book called 'The book of Vaadin', which will get you started and gives you a lot of information about the history of Vaadin, the architecture, the different components bundled with Vaadin and much more.

The architecture


I don't want to go into to much detail here, since you can find all this information on the Vaadin website, but from an architectural point of view I think these are the key concepts you need to know about Vaadin:

  • Everything is written in plain Java (no need for HTML templates, like with for instance Wicket)
  • All request processing happens on the server-side
  • GWT is used for the client-side rendering
  • Vaadin is more application than page oriented
  • Vaadin applications are state-full applications. Everything is stored in the user session.
  • You can program with Vaadin, like you would program with Swing or AWT.
Now let's try to actually start with a small application.

Getting started


There are several ways to get started with Vaadin. Vaadin has it's own plugin for Eclipse, NetBeans and a nice DZone refcard, but since I don't use either of those IDE's, I went for the Maven2 way. There are several Maven 2 archetypes available, which you can use from the command line or use from your favorite IDE (IntelliJ in my case).

Now let's create a clean Vaadin application by calling the archetype:

mvn archetype:generate \
-DarchetypeGroupId=com.vaadin \
-DarchetypeArtifactId=vaadin-archetype-clean \
-DarchetypeVersion=LATEST \
-DgroupId=com.jeroenreijn \
-DartifactId=vaadin-demo \
-Dversion=1.0-SNAPSHOT \
-Dpackaging=war

This will result in a new folder called 'vaadin-demo' and all this folder contains is a pom.xml, a web.xml and a simple HelloWorld Vaadin application. There is nothing more to it than that.

The application class is really small and simple. It just contains some components to get you going. This is what it looks like:

package com.jeroenreijn;

import com.vaadin.Application;
import com.vaadin.ui.Button;
import com.vaadin.ui.Window;

public class MyVaadinApplication extends Application
{
    private Window window;

    @Override
    public void init()
    {
        window = new Window("My Vaadin Application");
        setMainWindow(window);
        window.addComponent(new Button("Click Me"));
    }
}

Now that is nice and small right? The only thing this application does for now is that it creates a Window to put elements on with a default layout. Next to that a button with the label "Click me" is added to this window. It does not do much, but it's enough to get you going.

What's next?

I don't want to go into a full application in this post, but even after playing around with some more complex things, I have the feeling that I only scratched the surface. I think Vaadin is really interesting if you have to write rich web applications. The framework itself also has an addon directory filled with interesting and mature add-ons. I have some ideas I want to work out so I will keep you posted with my progress.

21 October 2010

Unit testing your HST2 components with EasyMock

Quality is an important aspect of every software development project. Writing unit tests is just one part of keeping an eye on quality. In this post I will try to explain how you can unit test your Hippo Site Toolkit (HST2) components, so you can be sure that the component still behaves as expected even after multiple maintenance cycles.

A mocking framework

Unit testing is the testing of software units (for instance HST2 components) in isolation. However, most units do not work alone, but they collaborate with other units, like the HST2 does for instance with a running JCR repository and a live HttpServletRequest (wrapped inside an HstRequest). To test a unit in isolation, we have to simulate these collaborations in our tests.
One way of working around such collaborations is by using Mock objects. A Mock Object is a test-oriented replacement for such a collaborator. It is configured to simulate the object that it replaces in a simple way. For this post I use EasyMock, but there are other mocking frameworks out there.

Setting up your environment

If you are regular reader, you might have noticed that I've been using Maven2 in most of my posts, so this time will not be different. To be able to test your HST components, you will need to add the following dependencies to your project/module pom.xml.

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.5</version>
  <scope>test</scope>
</dependency>

<dependency>
  <groupId>org.easymock</groupId>
  <artifactId>easymock</artifactId>
  <version>2.5.2</version>
  <scope>test</scope>
</dependency>

<dependency>
  <groupId>org.easymock</groupId>
  <artifactId>easymockclassextension</artifactId>
  <version>2.5.2</version>
  <scope>test</scope>
  <exclusions>
    <exclusion>
      <groupId>cglib</groupId>
      <artifactId>cglib-nodep</artifactId>
    </exclusion>
  </exclusions>
</dependency>

<dependency>
  <groupId>org.onehippo.cms7.hst</groupId>
  <artifactId>hst-mock</artifactId>
  <scope>test</scope>
</dependency>


Now that we have setup all the needed dependencies let's create an HST component to get started.

Basic HST2 Component


So let's start of with a simple/basic HST2 component. Here we have a simple component that tries to get a HippoBean wrapping a JCR node for the current request and puts the bean as an attribute on the request.

import org.hippoecm.hst.component.support.bean.BaseHstComponent;
import org.hippoecm.hst.content.beans.standard.HippoBean;
import org.hippoecm.hst.core.component.HstComponentException;
import org.hippoecm.hst.core.component.HstRequest;
import org.hippoecm.hst.core.component.HstResponse;

public class AbstractBaseHstComponent extends BaseHstComponent{

    @Override
    public void doBeforeRender(HstRequest request, HstResponse response) 
        throws HstComponentException {

        HippoBean bean = getContentBean(request);
        if(bean!=null) {
            request.setAttribute("document",bean);
        }
    }
}

Looks quite simple right? Now let's move on to the test.

The actual test

Now that we've seen what our component looks like, let's take a look at how we can test this class. The component doesn't do a lot, but there are a couple of things that we want to test:

  • that the getContentBean method is called
  • when the bean is not null the bean is set as an attribute on the request
  • there is an attribute on the request with the name document
  • the document from the request attribute is the same as the one put on the request

So now let's translate that into some code.

Before we can actually test our doBeforeRender method we need to do some setup before we can continue.

MockHstRequest fakeRequest;
MockHstResponse fakeResponse;
AbstractBaseHstComponent component;

@Before
public void setUp() throws Exception {
    fakeRequest = new MockHstRequest();
    fakeResponse = new MockHstResponse();
    component = createMockBuilder(AbstractBaseHstComponent.class).
                addMockedMethod("getContentBean", HstRequest.class).
                createMock();
}

Now looking at this setUp() method, you will notice that at first we create mocked versions of a request and response. These objects are necessary because they are parameters for our method under test. In a normal environment these objects will be created by the servlet container, but since we're unit testing we have to create these ourselves.

Next to that we create a mocked version of our AbstractBaseHstComponent. We do this because we need to mock the getContentBean method, which in a normal live environment performs interaction to a live JCR repository. The logic for getting the bean based on repository configuration is not useful for our test, so we mock the method and create a partial mock of the class.

Now let's have a look at the total test case and the actual test method.

import org.hippoecm.hst.content.beans.standard.HippoBean;
import org.hippoecm.hst.content.beans.standard.HippoDocument;
import org.hippoecm.hst.core.component.HstRequest;
import org.junit.Before;
import org.junit.Test;
import org.hippoecm.hst.mock.core.component.MockHstRequest;
import org.hippoecm.hst.mock.core.component.MockHstResponse;
import static org.easymock.classextension.EasyMock.*;
import static org.junit.Assert.*;

/**
 * Test for {@link com.jeroenreijn.site.components.AbstractBaseHstComponent}
 */
public class AbstractBaseHstComponentTest {

    MockHstRequest fakeRequest;
    MockHstResponse fakeResponse;
    AbstractBaseHstComponent component;

    @Before
    public void setUp() throws Exception {
        fakeRequest = new MockHstRequest();
        fakeResponse = new MockHstResponse();
        component = createMockBuilder(AbstractBaseHstComponent.class).
                addMockedMethod("getContentBean", HstRequest.class).
                createMock();
    }

    @Test
    public void testDocumentOnRequestAfterDoBeforeRender() throws Exception {

        HippoBean bean = new HippoDocument();

        //record the expected behavior
        expect(component.getContentBean(fakeRequest)).andReturn(bean);

        //stop recording and switch the mocked Object to replay state.
        replay(component);

        component.doBeforeRender(fakeRequest,fakeResponse);

        //verify the specified behavior has been used
        verify(component);

        assertSame(fakeRequest.getAttribute("document"),bean);
    }
}


As you might notice, the testDocumentOnRequestAfterDoBeforeRender() method tests the doBeforeRender method and checks all of the above requirements.

The next step


Even though you can create a mock of most objects quite easily, it's much better to have some native support/provided mock objects for most HST2 classes. Therefore I've added a patch to JIRA, which adds more mocked classes that can be used for testing, so you do not have to mock explicit methods. Next to that it will create test maven artifact, which you can use when testing your HST component without having to mock explicit methods or objects yourself.
Let me know if you run into any issues or have some ideas on improvement. It can make all our lives better.

Note/Update: This post was written at a time when the mock classes were not part of Hippo core (version 7.4). In the meantime this has changed and the classes can now be found in hst-mock artifact.


ps. I've just noticed that Shane Smith of iProfs created a similar post with using Mockito.

06 October 2010

Large heap dump analysis with Eclipse Memory Analyzer

Most developers working with Java hardly have to think about the memory footprint of their application that they wrote. The garbage collector inside the JVM will remove most waste, but what happens when not all waste can be removed or something is wrong inside the application? This may result in an exception that probably a lot of developers and system administrators have seen before: java.lang.OutOfMemoryError (OOME).
There are several causes for such an exception, but the most obvious is that there is memory leak somewhere in the application.

The situation

At one of my recent projects we were having some memory related issues on one of the production machines. The web application was running in Tomcat 6 and it appeared that at a certain point in time, the JVM tried to allocate twice the average memory it was using. Let's say from 2 Gb the memory footprint went up to 4GB. You might have guessed it, because only a couple of minutes later we were represented with the OOME message in the server log. It turned out that this was related to the amount and type of requests being handled by the application server. I was glad to find out it was not a memory leak, but more a warning that the total size of requests could allocate a lot of memory. If your application is running, it's hard to see what objects allocate memory. To get an insight on what the application was doing at the moment the OOME occurred, we configured the JVM to create a memory(heap) dump/snapshot at the moment that the OOME was thrown.

Generating a heap dump

Most of my clients run on the Sun(Oracle) JVM, so I will try to keep this post focussed on the instructions for the Sun JVM. In case your application server runs out of memory you can instruct the JVM to generate a heap dump when an OOME occurs. This heap dump will be generated in the HPROF binary format.

You can do this in by:

  1. Manually: by using 'jmap', which is available since JDK 1.5.
  2. Automatically by providing the following JVM command line parameter:
    -XX:+HeapDumpOnOutOfMemoryError

The size of the heap dump is around the same size as the configured max heap size JVM parameter.
So if you have set your max heap size to -Xmx512m , your heap dump will be around that size.

Analyzing the heap dump

Now you have the heap dump and want to figure out what was inside the heap at the moment the OOME occurred. There are several Java heap dump analyzers out there, where most of them can do more then just heap analysis. The products range from commercial to open source and these are the ones that I tried with my 4Gb .hprof file:


I was surprised to see that most of the above applications were unable to handle a file of this size. Eclipse Memory Analyzer was actually the only heap dump analyzer that was able to handle a heap dump of this size on my MacBookPro. All the other analyzers were unable to handle a file of this size. Apparently some of these tools tried to load the entire file into memory. On a laptop with only 4 Gb this will not fit.  Eclipse MAT was able to analyze this file within 5-10 minutes.

About Eclipse Memory Analyzer


One of the great things about Eclipse Memory Analyzer is that it starts indexing the heapdumps on first load. This makes the processing of the heapdump very fast and once you've parsed the entire heapdump, reopening it is a piece of cake, because it does not have to process it all over again.

Once you have the heapdump on your screen the dominator tree view is the most useful view and can give you a very good insight on what was loaded when the server ran out of memory.

Next to the statistical views there is also an automatic leak hunter available to help you figure out the problem as fast as possible.

Summary


If you ever have to analyze a heap dump I would recommend to use Eclipse Memory Analyzer. It's fast, easy to use and free.