Blog

Update your Vaadin 8 project to Java 11 and GWT 2.9.0

By  
Tatu Lund
Tatu Lund
·
On Feb 9, 2021 10:48:17 AM
·
In Product

Frame (24)

Vaadin 8 was originally built and designed when Java 8 was the newest and the coolest. You can see this in many parts of the API. For example, we use lambdas to implement listeners that only have one method, and use Optionals and Streams here and there. Vaadin 8 also uses GWT 2.8.2, which allows you to use Java 8 syntax in your client-side code.

However, Java has moved forward both as a programming language and as a runtime environment. 

The latter is an obvious reason to use Java 11 or newer versions in production environments, for example, to benefit from better garbage collection performance. But, this does not mean that you need to use any Java 11 syntax in your code. 

Updating to GWT 2.9.0

If you like, you can use Java 11 syntax in the server-side code of your Vaadin 8 application. However, GWT 2.8.2 limits you to using Java 8-compliant syntax in custom client-side code. You can arrange this by separating your client-side code into its own module and limiting its source level to Java 8.

But you may be thinking; what if you could enable Java 11 syntax in the whole project including the widgets? Could you have something like the example below in your Connector class for the widget extension?


@Connect(ResetButtonForTextField.class)

public class ResetButtonForTextFieldConnector extends

        AbstractExtensionConnector implements KeyUpHandler, AttachEvent.Handler {




    public static final String CLASSNAME = "resetbuttonfortextfield";

    private AbstractTextFieldConnector textFieldConnector;

    private VTextField textField;

    private Element resetButtonElement;


    @Override

    protected void extend(ServerConnector serverConnector) {

        serverConnector.addStateChangeHandler(event -> {

            Scheduler.get().scheduleDeferred(() -> {

                updateResetButtonVisibility();

            });

        });

        textFieldConnector = (AbstractTextFieldConnector) serverConnector;

        textField = (VTextField) textFieldConnector.getWidget();

        var textFieldStyle = CLASSNAME + "-textfield";

        textField.addStyleName(textFieldStyle);




        resetButtonElement = DOM.createDiv();

        var resetButtonStyle = CLASSNAME + "-resetbutton";

        resetButtonElement.addClassName(resetButtonStyle);




        textField.addAttachHandler(this);

        textField.addKeyUpHandler(this);

    }

 

And the answer is Yes. A newer version of GWT, 2.9.0, has been out for a while. We do not include it in Vaadin 8 out of the box yet, but the structure of Vaadin 8 dependencies allows overriding it in your local project. Let's take a look at how to do that.

To upgrade your Vaadin 8 application to use GWT 2.9.0, add the following property:


    <vaadin.gwt.version>2.9.0</vaadin.gwt.version>

 

Then add the dependencies to your pom.xml. If you have a multi-module project, you need to choose the module which defines the widgetset.


    <dependency>

        <groupId>com.google.gwt</groupId>

        <artifactId>gwt-dev</artifactId>

        <version>${vaadin.gwt.version}</version>

        <exclusions>

            <exclusion>

                 <groupId>org.eclipse.jetty</groupId>

                 <artifactId>apache-jsp</artifactId>

            </exclusion>

        </exclusions>

        <scope>provided</scope>

    </dependency>

    <dependency>

        <groupId>com.google.gwt</groupId>

        <artifactId>gwt-user</artifactId>

        <version>${vaadin.gwt.version}</version>

        <scope>provided</scope>

    </dependency>

 

It is important to define these with <scope>provided</scope>, otherwise your application will not start due conflict with asm. You do not need these libraries during runtime as they are used only when you build and compile the widgetset.

Monkey patching

Unfortunately, the above is not enough. There is one breaking change in GWT 2.9.0, but it is easy to patch it locally. You need to work with the module that contains your client-side code. Add this class to package com.google.gwt.dev.shell:


package com.google.gwt.dev.shell;




/**

 * Dummy class to fix compilation errors caused by references to the original

 * class that was removed in GWT 2.9.0. Does not, in fact, check for GWT version

 * updates.

 */

public final class CheckForUpdates {

    // NOP

}

 

We call this class shadowing technique monkey patching.

You can find a full multi-module proof of concept application in GitHub: https://github.com/TatuLund/gwt290-demo

 

Tatu Lund
Tatu Lund
Tatu Lund has a long experience as product manager in different industries. Now he is head of the team delivering Vaadin support and training services. You can follow him on Twitter - @ TatuLund
Other posts by Tatu Lund