Using Server-Push in a Vaadin app

Just a short post to show how easy it is with Vaadin 7 to use server push in an application.

When doing some tasks in a background thread in a Vaadin application, there probably will come the time when some data needs to be shown in the UI. But as these data changes come from background processing, there is no direct possibility to show them in the UI, as UI changes normally are only reflected after a communication roundtrip from client to server to client which happens as a reaction to some user interaction. So even if you update your UI components in a UI.access() call – which is needed for correct access from the worker thread – these changes will not show in the UI until the next click. This is not what the user wants.

As a solution for this, Vaadin offers server push, the following shows how to implement it. I am using a Vaadin-Spring-Boot project to create the basis setup. The UI just contains a label which will be constantly updated from a background thread with the current time.

The pom is modified to include the following dependency:

<dependency>
    <groupId>com.vaadin</groupId>
    <artifactId>vaadin-push</artifactId>
    <version>7.4.5</version>
</dependency>

Then the UI class is in addition to the @SpringUI annotation decorated with @Push.
The consequence of this is, that the framework after every call to access() will use a server push mechanism to update the UI in the browser.

/**
 * Copyright (c) 2015 sothawo
 *
 * http://www.sothawo.com
 */
package demo;

import com.vaadin.annotations.Push;
import com.vaadin.annotations.Theme;
import com.vaadin.server.VaadinRequest;
import com.vaadin.spring.annotation.SpringUI;
import com.vaadin.ui.Label;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;

import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.ForkJoinPool;

/**
 * UI class.
 *
 * @author P.J. Meisch (pj.meisch@sothawo.com).
 */
@Theme("valo")
@SpringUI
@Push
public class DemoUI extends UI {
    @Override
    protected void init(VaadinRequest vaadinRequest) {
        VerticalLayout layout = new VerticalLayout();
        layout.setMargin(true);
        layout.setSpacing(true);

        final Label labelTime = new Label("???");
        layout.addComponent(labelTime);

        // now in a background thread we constantly update the time
        final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss");
        ForkJoinPool.commonPool().submit(() -> {
            boolean keepGoing = true;
            while (keepGoing) {
                access(() -> labelTime.setValue(LocalTime.now().format(dateTimeFormatter)));
                try {
                    Thread.sleep(600);
                } catch (InterruptedException e) {
                    keepGoing = false;
                }
            }
        });

        setContent(layout);
    }
}

And this makes the browser happily display the always current time:

push-time

 

fix maven-release-plugin not committing changed pom.xml when using git repository

With one of my projects I just had the problem that the maven-release-plugin did not work as expected: I did a mvn release:prepare, answered the questions about the version number of the release and the next snapshot version, but the release plugin did not work as expected:

The version in the pom.xml was updated to the release version, the pom.xml was added to git stage, but not committed. After that, the new tag was created on the version that had still the pom.xml with the SNAPSHOT release, and the mvn release:perform was not building the release version, but still the snapshot version.

I don’t know wether this is a bug in the git version, the maven-release-plugin or the maven-scm-provider, but setting the maven components to the following fix versions (at the moment the actual ones to be found in maven central) solved the problem for me:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-release-plugin</artifactId>
            <version>2.5.2</version>
            <dependencies>
                <dependency>
                    <groupId>org.apache.maven.scm</groupId>
                    <artifactId>maven-scm-provider-gitexe</artifactId>
                    <version>1.9.4</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>

 

Using Spring-Boot configuration properties in your own classes

When writing a Spring-Boot application it is possible to use your own custom configuration classes which are injected by spring into your application and which  are configured in the application.properties file. There is even support for autocomplete support in the properties file editor in IntelliJ IDEA (I suppose there is something similar in Eclipse or NetBeans, but I haven’t tried that). This post shows how to achieve this.

Basically this is used for auto configuration of Spring-Boot components, but can be used in the Spring-Boot application as well.

The configuration class

Let’s assume we have a class named Support which represents our configuration:

/**
 * Copyright (c) 2015 sothawo
 *
 * http://www.sothawo.com
 */
package com.sothawo.sbconfig;

import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * @author P.J. Meisch (pj.meisch@sothawo.com).
 */
@Component
@ConfigurationProperties(prefix = "support")
public class Support {

    private Integer productId;

    private Contact contact;


    public Contact getContact() {
        return contact;
    }

    public void setContact(Contact contact) {
        this.contact = contact;
    }

    public Integer getProductId() {
        return productId;
    }

    public void setProductId(Integer productId) {
        this.productId = productId;
    }

    @Override
    public String toString() {
        return "Support{" +
                "productId=" + productId +
                ", contact=" + contact +
                '}';
    }

    public static class Contact {

        private String name;

        private String email;

        public String getEmail() {
            return email;
        }

        public void setEmail(String email) {
            this.email = email;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        @Override
        public String toString() {
            return "Contact{" +
                    "name='" + name + '\'' +
                    ", email='" + email + '\'' +
                    '}';
        }
    }
}

This is a plain POJO; it contains an inner class, but that is only for the purpose of showing how Spring Boot configures a field that is itself a class. What marks this as a configuration class is the @ConfigurationProperties annotation, which by it’s prefix argument defines the prefix string to use in the properties file.

Edit 2015-09-21: added missing @Component annotation.

Enable the Spring Boot annotation processor

To have the annotation processed it is necessary to add the following dependency to the project’s pom.xml (notice that it’s optional):

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

After compiling the project there is a new file in the target/META-INF directory named spring-configuration-metadata.json. This is needed for autocomplete support, it contains the names, types and class information of the configuration class:

{
  "groups": [
    {
      "name": "support",
      "type": "com.sothawo.sbconfig.Support",
      "sourceType": "com.sothawo.sbconfig.Support"
    },
    {
      "name": "support.contact",
      "type": "com.sothawo.sbconfig.Support$Contact",
      "sourceType": "com.sothawo.sbconfig.Support",
      "sourceMethod": "getContact()"
    }
  ],
  "properties": [
    {
      "name": "support.contact.email",
      "type": "java.lang.String",
      "sourceType": "com.sothawo.sbconfig.Support$Contact"
    },
    {
      "name": "support.contact.name",
      "type": "java.lang.String",
      "sourceType": "com.sothawo.sbconfig.Support$Contact"
    },
    {
      "name": "support.product-id",
      "type": "java.lang.Integer",
      "sourceType": "com.sothawo.sbconfig.Support"
    }
  ]
}

Using the configuration object

The configuration object is used by injecting it in a Spring bean, for example like this:

/**
 * Copyright (c) 2015 sothawo
 *
 * http://www.sothawo.com
 */
package com.sothawo.sbconfig;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**
 * @author P.J. Meisch (pj.meisch@sothawo.com).
 */
@Component
@EnableConfigurationProperties(Support.class)
public class SupportInfo {
    @Autowired(required = false)
    private Support support;

    @PostConstruct
    public void init() {
        if (null == support) {
            System.out.println("no support");
        } else {
            System.out.println(support.toString());
        }
    }
}

Configuring the object

IntelliJ supports editing the application.properties file with code completion:

sbcfg01

This shows the available configuration properties as well as their types and default values (if the fields of the configuration class are initialized with values). The screenshot shows how field names and inner classes are mapped to the corresponding property entries.

Custom theme for a Vaadin – Spring-boot application

Recently I wrote an application based on Vaadin Spring-boot, and when I needed to modify the theme of the application I needed to do some research as how to achieve that. I think that at the time the combination of Vaadin and Spring-boot is still pretty new so that information still must be sought. So in this post I describe the necessary steps.

I use the following versions of different tools:

  • Oracle JDK 1.8.0_45
  • vaadin 7.4.5
  • vaadin-spring-start 1.0.0.beta3
  • spring-boot 1.2.3.RELEASE
  • spring 4.1.6.RELEASE

My IDE is IntelliJ IDEA 14.1.3

Creating the basic application

I create the application project (named vsbt for vaadin spring boot theme) by using the Spring Initializr from within IDEA, but it can be done via the Website https://start.spring.io as well:

vsbt01

For this demo I set up a project with the following properties that has only Vaadin as a dependency:

vsbt02

vsbt03

After finishing the setup I have an IDEA maven project with the basic application class, but still with no UI:

vsbt04

So to have something visible, I add a MainUI class which uses the valo theme and which just inserts a button in the UI. The button is nonfunctional, as this demo is only concerning with theming the UI and not with functionality:

/**
 * Copyright (c) 2015 sothawo
 *
 * http://www.sothawo.com
 */
package org.sothawo.vsbt;

import com.vaadin.annotations.Theme;
import com.vaadin.server.VaadinRequest;
import com.vaadin.spring.annotation.SpringUI;
import com.vaadin.ui.Button;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;

/**
 * @author P.J. Meisch (pj.meisch@sothawo.com).
 */
@Theme("valo")
@SpringUI
public class MainUI extends UI {
    @Override
    protected void init(VaadinRequest vaadinRequest) {
        VerticalLayout layout = new VerticalLayout();
        layout.setSizeFull();
        layout.setMargin(true);
        layout.setSpacing(true);

        layout.addComponent(new Button("This is a button"));

        setContent(layout);
    }
}

Compiling and running the application gives the following result in the browser:

vsbt05

Changing the theme

Now for changing the theme. I want to create a theme named colored where I change some colors. The first step ist to put the theme files (sass files) in the src/main/webapp/VAADIN/themes/colored folder:

vsbt06

 

The styles.scss file:

@import "addons.scss";
@import "colored.scss";

The colored.scss file:

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

@mixin colored {
  @include valo;

  .v-app {
    background-color: red;
  }

  .v-button {
    background-image: none;
    background-color: yellow;
  }
}

@include colored;

I don’t get into the details of sass files here. In the MainUI class the annotation for the theme must be changed to @Theme("colored").

When I now start the program after building the program with the following command:

mvn clean package
cd target
java -jar vsbt-0.0.1-SNAPSHOT.jar

then the browser shows no theme:

vsbt07

The reason for this is that the files that are located under the src/main/webapp directory are not considered when the jar is packaged, this is only done when building a war file. So the first step that needs to be done is to specify this directory as a resource directory in the maven pom.xml:

<build>
  <resources>
    <resource>
      <directory>src/main/resources</directory>
    </resource>
    <resource>
      <directory>src/main/webapp</directory>
    </resource>
  </resources>
  ...
</build>

One might be tempted to move the VAADIN/themes/colored folder to src/main/resources, but there is still a problem to be solved. When building and running the application, the logging output shows an error message like:

un 02, 2015 9:21:14 PM com.vaadin.server.VaadinServlet persistCacheEntry
WARNUNG: Error persisting scss cache /private/var/folders/xw/1zt9sly53_76h29g7067_y700000gp/T/tomcat-docbase.6378846904000133878.8080/VAADIN/themes/colored/styles.scss.cache
java.io.FileNotFoundException: /private/var/folders/xw/1zt9sly53_76h29g7067_y700000gp/T/tomcat-docbase.6378846904000133878.8080/VAADIN/themes/colored/styles.scss.cache (No such file or directory)
        at java.io.FileOutputStream.open0(Native Method)

This happens because the sass compiler – at least on my Mac – has problems with persisting the compiled css file. To remove that error it is necessary to add the sass compiler to the compile step in the maven pom.xml (and this is the reason to leave the files in the src/main/webapp directory, it’s there that the compiler searches for them):

<dependencies>
        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-themes</artifactId>
        </dependency>
</dependencies>
...
<plugins>
    <plugin>
        <groupId>com.vaadin</groupId>
        <artifactId>vaadin-maven-plugin</artifactId>
        <executions>
            <execution>
                <goals>
                    <goal>update-theme</goal>
                    <goal>compile-theme</goal>
                    <!--
                    <goal>clean</goal>
                    <goal>resources</goal>
                    <goal>update-widgetset</goal>
                    <goal>compile</goal>
                    -->
                </goals>
            </execution>
        </executions>
    </plugin>
</plugins>

When now compiling the project, the addons.scss and the colored.css files are created in the theme directory and packaged in the application, and after packaging and running, the browser shows the following application with no more logged errors:

vsbt08

I hope this post can help if somebody needs to theme a vaadin spring-boot application and has the same problems finding out where to put the files and how to compile them.