How to: Vaadin add-ons and Maven

Introduction

One (of the many) thing I like about Vaadin, is its community of ‘add-ons’ to the Vaadin framework – what they call the Vaadin Directory. An ‘add-on’ is a community-contributed addition to the framework, and can be anything from for example a new client-side widget to a Lazy loading container for a data table. Something similar I would definitely like to see for Activiti!

Vaadin widgets are basically precompiled GWT widgets. GWT widgets on itself are Java classes, but the GWT compiler compiles them to Javascript that works accross all browser. So, when you want to use a certain add-on (that has new client-side visuals) in your Vaadin webapp, you will have to compile them yourself since you must include the new Javascript in your webapp.

If you are using the Vaadin Eclipse plugin, all is happy and fine. Just add the add-on jar to your project, and the plugin autodetects and compiles the new widgets. However, when your webapp is built using Maven, it’s not that simple. But throwing out Maven and manually copying all your dependency jars is not necessary at all. It’s 2011 after all.

The default way of doing the GWT compilation in Maven is, in my opinion, not efficient. So let me guide you through what setup works the best for me and how I tweaked the Maven pom.xml.

For the impatient-ones: check the source on github: https://github.com/jbarrez/vaadin-mvn-addon

Creating a new Vaadin webapp with Maven

This step is well-documented, just check the Vaadin wiki.

Short version: use following archetype:

mvn archetype:generate -DarchetypeGroupId=com.vaadin-DarchetypeArtifactId=vaadin-archetype-clean -DarchetypeVersion=6.5.6 -DgroupId=com.jorambarrez -DartifactId=vaadin-mvn-addon -Dversion=1.0 -Dpackaging=war

Add the add-on

In this example webapp, I’m going to use two cool Vaadin add-ons:

  • Paperstack: a container that allows to display components as pages of a book
  • Refresher: a client side component that polls the server for UI changes

Both add-ons have new client side widgets, so a run through the GWT compiler is definitely needed.

Tweak pom.xml

Open up the pom.xml. The archetype already generated all you need to work with custom add-ons. Look for commented sections, and just uncomment them. That’s all there is.

Create the webapp

The following Vaadin webapp shows a simple use of these two components. We’ll just display ‘Activiti’, with each character on a new page of the paperstack component. We also have a button, that will auto-flip through the pages using the Refresher component and a server-side thread:

public class MyVaadinApplication extends Application {

  private static final String DISPLAYED_WORD = "ACTIVITI";

  private Window window;
  private Refresher refresher;
  private Button goButton;
  private PaperStack paperStack;

  @Override
  public void init() {
    window = new Window("My Vaadin Application");
    setMainWindow(window);

    initGoButton();
    initPaperStack();
  }

  private void initGoButton() {
    goButton = new Button("Flip to the end");
    window.addComponent(goButton);

    goButton.addListener(new ClickListener() {
      public void buttonClick(ClickEvent event) {
        goButton.setEnabled(false);
        startRefresher();
        startPageFlipThread();
      }
    });
  }

  private void startRefresher() {
    refresher = new Refresher();
    window.addComponent(refresher);
    refresher.setRefreshInterval(100L);
  }

  private void startPageFlipThread() {
    Thread thread = new Thread(new Runnable() {
      public void run() {
        goButton.setEnabled(false);
        int nrOfUpdates = DISPLAYED_WORD.length() - 1;
        while (nrOfUpdates >= 0) {
          paperStack.navigate(true);
          nrOfUpdates--;
          try {
            Thread.sleep(2000L);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
        }

        // Remove refresher when done (for performance)
        goButton.setEnabled(true);
        window.removeComponent(refresher);
        refresher = null;
      }
    });
    thread.start();
  }

  private void initPaperStack() {
    paperStack = new PaperStack();
    window.addComponent(paperStack);

    for (int i=0; i<DISPLAYED_WORD.length(); i++) {
      VerticalLayout verticalLayout = new VerticalLayout();
      verticalLayout.setSizeFull();
      paperStack.addComponent(verticalLayout);

      // Quick-hack CSS since I'm to lazy to define a styles.css
      Label label = new Label("<div style=\"text-align:center;color:blue;font-weight:bold;font-size:100px;text-shadow: 5px 5px 0px #eee, 7px 7px 0px #707070;\">" + DISPLAYED_WORD.charAt(i) + "</div>", Label.CONTENT_XHTML);
      label.setWidth(100, Label.UNITS_PERCENTAGE);
      verticalLayout.addComponent(label);
      verticalLayout.setComponentAlignment(label, Alignment.MIDDLE_CENTER);
    }
  }

Tweak web.xml

To make Vaadin aware of the custom add-ons, add following lines to the Vaadin Application Servlet:

<init-param>
  <param-name>widgetset</param-name>
  <param-value>com.jorambarrez.CustomWidgetset</param-value>
</init-param>

Also add a file ‘CustomWidgetset.gwt.xml’ in the package com.jorambarrez (matching whatever you have put in the web.xml). Just copy the following lines, and don’t worry about putting the add-on GWT descriptors there (which would be logical), the maven plugins will find them automatically in the add-on jars.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC
    "-//Google Inc.//DTD Google Web Toolkit 1.7.0//EN"
    "http://google-web-toolkit.googlecode.com/svn/tags/1.7.0/distro-source/core/src/gwt-module.dtd">
<module>
    <inherits name="com.vaadin.terminal.gwt.DefaultWidgetSet" />
</module>

Run the webapp

Go to your project, and execute following command:

mvn clean package jetty:run

This starts up a Jetty webserver and deploys our webapp. You should now be able to play around with the webapp.

The problem

When running the previous command, you’ll should see the GWT compiler kicking in and compiling the custom widget. The problem is, the GWT compiler does take its time to do its magic (1.30 minutes on my machine, while simply starting Jetty takes 5 seconds).

I’m not going to sit and watch the GWT compiler sprinkling pixie dust over my add-ons every frick’n time when I want to run my app. Sure JRebel, could help out a lot here, but it should most definitely not be necessary to have my widgets compiled every time. After all, I’m not changing these add-ons at-all, right.

Tweaking pom.xml (The Sequel)

So we just learned that the default pom.xml generated by the Vaadin archetype isn’t friendly when it comes to add-ons. If you take a look at the configuration of the GWT compiler plugin, you’ll notice that the compiled widgets are added to the target folder, and not in the sources of your project:

<webappDirectory>${project.build.directory}/${project.build.finalName}/VAADIN/widgetsets</webappDirectory>

If we change that to our source folder:

<webappDirectory>src/main/webapp/VAADIN/widgetsets</webappDirectory>

the result of the GWT compilation is put in the source of my webapp. This also means I can just check them in together with the rest of my webapp.

The only thing we now need to do, is to make sure we don’t recompile the widgets on every run. I’ve chosen to simply put it in a profile as follows:

<profiles>
  <profile>
    <id>compile-widgetset</id>
    <build>
    <plugins>
      <plugin>
	<groupId>org.codehaus.mojo</groupId>
	<artifactId>gwt-maven-plugin</artifactId>
        ....

Whenever I now add a new add-on to the project, I now run the following command:

mvn -Pcompile-widgetset clean compile

and it will compile all add-ons and put the result in my source folders. Running the Jetty webserver as shown above, will now just copy these sources to the war file and boot time is reduced to a minumum again (5 seconds here).

Source

The whole webapp as described in the above steps in fully available on GitHub: https://github.com/jbarrez/vaadin-mvn-addon

Conclusion

Using add-ons with Maven is not that hard, all of that is well-documented (as anything in Vaadin). However, the Maven archetype generates a Maven configuration that isn’t that efficient since it recompiles the add-on widgets on every run. The above steps show how to tweak the config to make it more suitable for real rapid development!

Any comments or improvements are welcome of course!

12 Comments

  1. matf April 28, 2011

    Thanks, that’s something I meant to look at for a while now.

  2. Joonas April 30, 2011

    Would you like to add a note on this to http://vaadin.com/wiki/-/wiki/Main/Using%20Vaadin%20with%20Maven ?

  3. Glenn Dejaeger June 26, 2011

    Great article! I also used to have problems with Vaadin-addons in a Maven project and I also didn’t want to compile those widgetsets over and over again because the source code doesn’t change.

    Keep up the good work!

  4. dejan December 10, 2011

    Kudos :)

    May the force be with you !!!

  5. Franck March 20, 2012

    Just to say thanks for this entry!
    It helped me a lot to manage to compile and use the CKeditor add-on for Vaadin with maven

  6. [...] 5/1/12 3:36 PM as a reply to rajesh kumar kumar. We just started using the method described in this blog. It generates the widgetset into the source tree instead of the target tree, so the bits are always [...]

  7. [...] option the first time because we’re using a Vaadin add-on. Thank you to this blog for showing me how to put the widget compilation into its own [...]

  8. Gattaka September 21, 2012

    Thx ! This saved my time ! :)

  9. Sönke July 12, 2013

    Wouldn’t it be possible to put the addons and custom UI stuff into a separate maven module and use the incremental build feature. So you would only have the GWT compile when it is needed.
    Eliminates the risk of forgetting to do it manually…

  10. Joram Barrez July 15, 2013

    @Sonke: That would be an alternative, yes. Although you still can’t forget to rebuild the other project then ;-)

  11. xproph October 27, 2013

    Great thanks.

    I have just decided to start using Vaadin and the first thing that annoyed me was the long process of updating widgets.

    Cool thanks again for help.


    devmain

  12. […] Joram Barrez uses a Vaadin archetype to do some of this and takes it a bit further, by isolating widget set compilation to a maven profile: http://www.jorambarrez.be/blog/2011/04/28/howto-vaadin-addon-maven/ […]

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>