About Joram Barrez

Joram is an all-around software engineer with a keen interest in anything that is slightly related to software development. He left JBoss for starting the Activiti project together with Tom Baeyens (also ex-JBoss) at Alfresco .Besides Activiti, he is also heavily involved with iOS development and the workflow features for the Alfresco Mobile app.

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!

Reference: How to: Vaadin add-ons and Maven from our JCG partner Joram Barrez at the Small steps with big feet blog

Related Articles :

Related Whitepaper:

Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions

Get ready to program in a whole new way!

Functional Programming in Java will help you quickly get on top of the new, essential Java 8 language features and the functional style that will change and improve your code. This short, targeted book will help you make the paradigm shift from the old imperative way to a less error-prone, more elegant, and concise coding style that’s also a breeze to parallelize. You’ll explore the syntax and semantics of lambda expressions, method and constructor references, and functional interfaces. You’ll design and write applications better using the new standards in Java 8 and the JDK.

Get it Now!  

One Response to "Vaadin add-ons and Maven"

  1. warsame bashir says:

    Hello

    Are the steps any different for a Spring ROO + vaadin project using MAVEN. I did not use the archetypes to create my project and when i add the above changes to my pom.xml file, i get a “vaadin” unknown error given by Maven

Leave a Reply


3 + one =



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

15,153 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books