Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Simple Everyday Tips for Vaadin Developers (Part 1: Vaadin 6 to 7)

DZone's Guide to

Simple Everyday Tips for Vaadin Developers (Part 1: Vaadin 6 to 7)

A tutorial to migrate the JBoss BRMS Demo from Vaadin 6 to 7.

· Java Zone
Free Resource

Learn how to troubleshoot and diagnose some of the most common performance issues in Java today. Brought to you in partnership with AppDynamics.

Introduction

Everything started with the idea of migrating the JBoss BRMS Demo from Vaadin 6 to 7 and using the new Vaadin CDI Add-on. Since this is only a demo, the migration was relatively simple. Nevertheless, I found a lot of interesting code enhancement tips that can maximize the utilization of Vaadin core features and make the project more solid from UI perspective.

JBoss BRMS Demo running with Vaadin 6

JBoss BRMS Demo running with Vaadin 6

This series will be divided into five parts:

  1. Migrating From Vaadin 6 to Vaadin 7
  2. UI abstraction and using Vaadin CDI Add-on
  3. Styling Vaadin components and using Add-ons
  4. Data modeling in Vaadin
  5. Simple use case for Vaadin Grid

1. Migrating from Vaadin 6 to Vaadin 7

A quick look into the source code to get an idea about the structure and how things work, essentially we have the main UI and entry point:

com.redhat.coolstore.web.CoolStoreApplication

And we have two Views holding the layout of each side of the splitter:

com.redhat.coolstore.ui.ProductsView

com.redhat.coolstore.ui.ShoppingCartView

From the backend side, we have data entities located under the model package:

com.redhat.coolstore.model.*

And backend services located under:

com.redhat.coolstore.service.*

We also have the BRMSUtil, which is the core of this demo, that demonstrates how to initiate KieServices and retrieve either a stateless or stateful session. We will find it later injected in the ShoppingCartServiceImplBRMS service and used to calculate shopping cart values and promotions.

I will not go through all the backend details, probably we will not touch it at all, but it’s worth checking out the tutorial videos in the main project README file to learn more about the infrastructure behind those services.

Let’s start by walking through the minimum essential steps to compile the project with Vaadin 7 libraries. Luckily, the demo is using maven. So the first step would be to replace the old artifacts with the new ones, and see where the code won’t compile.

So I removed the following artifact:

<dependency>
  <groupId>com.vaadin</groupId>
  <artifactId>vaadin</artifactId>
  <version>6.8.3</version>
  <scope>compile</scope>
  <artifactId>vaadin-themes</artifactId>
</dependency>

And replaced it by:

<dependency>
  <groupId>com.vaadin</groupId>
  <artifactId>vaadin-server</artifactId>
</dependency>

<dependency>
  <groupId>com.vaadin</groupId>
  <artifactId>vaadin-client</artifactId>
  <scope>provided</scope>
</dependency>

We also need to place a BOM in the dependency management:

<dependency>
  <groupId>com.vaadin</groupId>
  <artifactId>vaadin-bom</artifactId>
  <version>7.5.10</version>
  <type>pom</type>
  <scope>import</scope>
</dependency>

And finally the Vaadin Add-ons repository:

<repository>
  <id>vaadin-addons</id>
  <url>http://maven.vaadin.com/vaadin-addons</url>
</repository>

The project was using the cdiutils Add-on for Vaadin 6, which is not compatible with Vaadin 7. Since we will replace it with the new official Vaadin CDI Add-on, it’s safe to take it out from the pom file for now, just to make things compile and work.

Related commit: Upgrade maven dependencies

 At this point we have some errors in the code complaining about old APIs that are no longer available or got changed. But before fixing those, let’s also fix the new theming structure and widgetset used by Vaadin 7. I don’t know by heart the exact configuration so the easiest thing I thought of is to create a new maven-based project using an archetype and copy the proper configuration from it.

To start off, let’s include the maven plugin for theme and widgetset compilation:

<plugin>
  <groupId>com.vaadin</groupId>
  <artifactId>vaadin-maven-plugin</artifactId>
  <version>7.5.10</version>
  <configuration>
    <extraJvmArgs>-Xmx512MXss1024k</extraJvmArgs>
    <webappDirectory>${basedir}/target/classes/VAADIN/widgetsets</webappDirectory>
    <draftCompile>false</draftCompile>
    <compileReport>false</compileReport>
    <style>OBF</style>
    <strict>true</strict>
  </configuration>
  <executions>
    <execution>
      <goals>
        <goal>update-theme</goal>
        <goal>update-widgetset</goal>
        <goal>compile</goal>
        <goal>compile-theme</goal>
      </goals>
    </execution>
  </executions>
</plugin>

And remove the old GWT dependencies, we no longer need them in the pom file and they will conflict with Vaadin 7:

<dependency>
  <groupId>com.google.gwt</groupId>
  <artifactId>gwt-user</artifactId>
  <version>2.3.0</version>
  <scope>compile</scope>
</dependency>

<dependency>
  <groupId>com.google.gwt</groupId>
  <artifactId>gwt-dev</artifactId>
  <version>2.3.0</version>
</dependency>

Related commit: Upgrade pom with newer deployment lifecycle

We have an old Reindeer theme in the project, so I replaced it with a Valo-based theme and renamed it to match the default project structure. In src/main/webapp/VAADIN/themes/ rename reindeer-ext folder to coolstoretheme then create addons.scss and coolstoretheme.scss files successively with the following contents:

@mixin addons {

}

@import "../valo/valo.scss";

And:

@mixin coolstoretheme {
  @include valo;

  // Old custom theme would have been placed here
}

Modify the contents of styles.css to contain the following:

@import "coolstoretheme.scss";
@import "addons.scss";

.coolstoretheme {
  @include addons;
  @include coolstoretheme;

}

Related commit: Create Vaadin 7 theme based on Valo

Similarly, I get a copy of the content of the default widgetset and include it in our project, under src/main/resources/com/redhat/coolstore/web/ a new file CoolStoreApplicationWidgetset.gwt.xml with the following contents:

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

Related commit: Create default widgetset

The next step is to fix the errors in the code. The first set of errors were found in ProductsView where CheckBox was assigned a ClickListener:

cb.addListener(new ClickListener() {

In Vaadin 7, CheckBox no more extends Button, and ClickListener should be replaced with a ValueChangeListener:

cb.addValueChangeListener(new ValueChangeListener() {

And in a single component container like ProductsView and ShoppingCartView where it accepts only one component (because both extend Panel), the new API is refined to use setContent instead of addComponent.

addComponent(vl);

Replace by:

setContent(vl);

Related commit: Initial Vaadin 7 upgrade

Now for the main UI, let’s disable anything related to CDI for now, so I initialized a default UI class:

public class CoolStoreApplication extends UI implements ClickListener {

And default servlet class:

@WebServlet(urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true)
@VaadinServletConfiguration(ui = CoolStoreApplication.class, productionMode = false)
public static class Servlet extends VaadinServlet {}

The init method now takes a VaadinRequest as a parameter:

public void init() {

Replaced by:

public void init(VaadinRequest request) {

And the core UI is a single component container as well (similar to Panel) you no longer need to getMainWind0w:

Window mainWindow = new Window("Red Hat Cool Store");
setMainWindow(mainWindow);
getMainWindow().removeAllComponents();
getMainWindow().addComponent(vl);

Replaced by:

setContent(vl);

You can annotate the UI class by Title:

@Title("Red Hat Cool Store")

Also to show a notification, you no longer need to do this:

getMainWindow().showNotification("Adding item(s) to cart.");

Simple call to the static method show will do the job:

Notification.show("Adding item(s) to cart.");

Finally let’s annotate the UI with the newly created Theme and Widgetset:

@Theme("coolstoretheme")
@Widgetset("com.redhat.coolstore.web.CoolStoreApplicationWidgetset")

Related commit: Upgrade UI entry point with theme and default UI without CDI

Lady : “You can’t walk there! Didn’t you see the giant Falling Stones warning?!”
Programmer : “We don’t care about warnings. We only care about errors."

The code compiles, there are no more errors but there are some warnings. We can probably ignore them and everything will just work, but fixing them is also a good practice. The warnings here are all about deprecated APIs and fixing them is quite straightforward. Instead of using addListener for the buttons, use addClickListener.

.addListener(app);

Replace by:

.addClickListener(app);

And to check the value of a CheckBox, just like any other field, call getValue:

cb.booleanValue()

Replace by:

cb.getValue()

Related commit: Replace deprecated APIs with newer version

Here is how the demo looks like so far after those modifications:

Here is how the demo looks like so far after those modifications

Hurray! The code compiles and works, migration is successful. In the upcoming part of this article, we will abstract the UI and integrate CDI.

Understand the needs and benefits around implementing the right monitoring solution for a growing containerized market. Brought to you in partnership with AppDynamics.

Topics:
vaadin ,java ,cdi ,ui ,ux ,brms ,jboss

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}