How can I compile only necessary widgets in Vaadin 7 with Maven?

raspacorp picture raspacorp · Jan 8, 2014 · Viewed 12k times · Source

I am new to the Vaadin framework which I looks very interesting, using eclipse and maven to develop and build my application I find pretty annoying that every time I do a mvn clean install it will take so long time to build the app, I found that this is because it compiles the whole set of widgets.

Even if I am only using a Button in my layout it will take so much on building the app.

I have researched for some time in the Internet and 2 books but cannot find enough information about how to make it to only compile components that I am using and not the whole set.

I created the project by using the maven archetype:

mvn archetype:generate -DarchetypeGroupId=com.vaadin -DarchetypeArtifactId=vaadin-archetype-application -DarchetypeVersion=7.1.9

I am sure that the widgetset is being compiled every time I build the war, when I do a mvn clean it removes the directory: /src/main/webapp/VAADIN/widgetsets and /src/main/webapp/VAADIN/gwt-unitCache

When I run mvn install the build will last for more than 3 minutes:

...
[INFO]    Compiling 6 permutations
[INFO]       Compiling permutation 0...
[INFO]       Process output
[INFO]          Compiling
[INFO]             Compiling permutation 1...
[INFO]       Process output
[INFO]          Compiling
[INFO]             Compiling permutation 3...
[INFO]       Process output
[INFO]          Compiling
[INFO]             Compiling permutation 2...
[INFO]       Compiling permutation 4...
[INFO]          Compiling
[INFO]             Compiling permutation 5...
[INFO]    Compile of permutations succeeded
[INFO] Linking into /.../example/src/main/webapp/VAADIN/widgetsets/com.my.example.AppWidgetSet; Writing extras to /.../example/target/extra/com.my.example.AppWidgetSet
[INFO]    Link succeeded
[INFO]    Compilation succeeded -- 167.103s
[INFO] 
[INFO] --- maven-war-plugin:2.2:war (default-war) @ ade ---
[INFO] Packaging webapp
[INFO] Assembling webapp [example] in [/.../example/target/example-0.1.0-SNAPSHOT]
[INFO] Processing war project
[INFO] Copying webapp resources [/.../example/src/main/webapp]
[INFO] Webapp assembled in [562 msecs]
[INFO] Building war: /.../example/target/example-0.1.0-SNAPSHOT.war
[INFO] 
[INFO] --- maven-install-plugin:2.4:install (default-install) @ ade ---
[INFO] Installing /.../example/target/example-0.1.0-SNAPSHOT.war to /.../example/0.1.0-SNAPSHOT/example-0.1.0-SNAPSHOT.war
[INFO] Installing /.../example/pom.xml to /.../example/0.1.0-SNAPSHOT/example-0.1.0-SNAPSHOT.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3:03.768s
[INFO] Finished at: Fri Jan 10 00:10:45 EST 2014
[INFO] Final Memory: 16M/81M
[INFO] ------------------------------------------------------------------------

After this the directory /src/main/webapp/VAADIN/widgetsets is generated again containing the following directories:

WEB-INF             
com.my.example.AppWidgetSet

It also generates /src/main/webapp/VAADIN/gwt-unitCache

Answer

atmo picture atmo · Jan 15, 2014

Do you need a custom widgetset? If you're not using any widget addons, and since your're new to Vaadin I am assuming that you did not create your own widgets yet(?), you can simply use the precompiled widgetset provided by Vaadin. To do this, remove any xxx.gwt.xml file from your project, and replace the reference to it in web.xml with com.vaadin.DefaultWidgetset.

web.xml:

<init-param>
    <name>widgetset</name>
    <value>com.vaadin.DefaultWidgetSet</value>
</init-param>

pom.xml:

<dependency>
    <groupId>com.vaadin</groupId>
    <artifactId>vaadin-client-compiled</artifactId>
    <version>7.1.9</version>    <!-- or whatever version you're using -->
</dependency>

If you do need a custom widgetset (and if you don't now, chances are that you will need one further down the road), do yourself a favor and put it in a separate project. In my experience, a widgetset very seldom changes, so why include it in a project that constantly changes. The default widgetset mentioned above, provided by Vaadin, is the prefect blueprint for building one. Just build your own, and copy its structure from vaadin-client-compiled.jar. You can use your favourite maven build helper for that, mine is assembly. Just create a maven project, setup pom.xml, add a xxx.gwt.xml and make sure web.xml contains a reference to it. My own setup looks something like what you see below.

pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <name>MyWidgetset</name>
    <groupId>com.company</groupId>
    <artifactId>mywidgetset</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <vaadin.version>7.1.9</vaadin.version>
        <vaadin.plugin.version>7.1.9</vaadin.plugin.version>
    </properties>

    <dependencies>
        <!-- vaadin -->
        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-client</artifactId>
            <version>${vaadin.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-client-compiler</artifactId>
            <version>${vaadin.version}</version>
            <scope>provided</scope>
        </dependency>

        <!-- custom widgets (NOTE: addons without a widget do not belong here) -->
        <dependency>
            <groupId>org.vaadin.addons</groupId>
            <artifactId>filteringtable</artifactId>
            <version>0.9.3.v7</version>
        </dependency>
        <dependency>
            <groupId>org.vaadin.addons</groupId>
            <artifactId>popupbutton</artifactId>
            <version>2.3.0</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!-- vaadin update widgetset -->
            <plugin>
                <groupId>com.vaadin</groupId>
                <artifactId>vaadin-maven-plugin</artifactId>
                <version>${vaadin.plugin.version}</version>

                <configuration>
                    <extraJvmArgs>-Xmx512M -Xss1024k</extraJvmArgs>
                    <webappDirectory>${basedir}/target/VAADIN/widgetsets</webappDirectory>
                    <hostedWebapp>${basedir}/target/VAADIN/widgetsets</hostedWebapp>
                    <force>false</force>
                    <strict>true</strict>
                    <noServer>true</noServer>
                    <compileReport>true</compileReport>
                    <style>OBF</style>
                    <runTarget>http://localhost:8080/</runTarget>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>resources</goal>
                            <goal>update-widgetset</goal>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.4</version>
                <configuration>
                    <appendAssemblyId>false</appendAssemblyId>
                    <descriptors>
                        <descriptor>src/main/resources/assembly.xml</descriptor>
                    </descriptors>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

        </plugins>
    </build>

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

assembly.xml:

<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">

    <id>build-my-widgetset-jar</id>
    <formats>
        <format>jar</format>
    </formats>

    <includeBaseDirectory>false</includeBaseDirectory>

    <fileSets>
        <fileSet>
            <directory>${basedir}/target/VAADIN/widgetsets</directory>
            <outputDirectory>/VAADIN/widgetsets</outputDirectory>
            <excludes>
                <exclude>WEB-INF/</exclude>
            </excludes>
        </fileSet>
    </fileSets>
</assembly>

MyWidgetset.gwt.xml:

<?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.DefaultWidgetSet" />

    <inherits name="org.tepi.filtertable.gwt.FilterTableWidgetset" />

    <inherits name="org.vaadin.hene.popupbutton.widgetset.PopupbuttonWidgetset" />

</module>

web.xml:

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">

    <display-name>MyWidgetset</display-name>

    <servlet>
        <servlet-name>MyWidgetset</servlet-name>
        <servlet-class>com.vaadin.server.VaadinServlet</servlet-class>
        <init-param>
            <param-name>ui</param-name>
            <param-value>com.company.mywidgetset.App</param-value>    <!-- use it for testing the widgetset-->
        </init-param>
        <init-param>
            <param-name>widgetset</param-name>
            <param-value>com.company.mywidgetset.MyWidgetset</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>MyWidgetset</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
</web-app>

project structure:

|   pom.xml
|
\---src
    +---main
    |   +---java
    |   |   \---com
    |   |       \---company
    |   |           \---mywidgetset
    |   |                   App.java
    |   |                   MyWidgetset.gwt.xml
    |   |
    |   +---resources
    |   |       assembly.xml
    |   |
    |   \---webapp
    |       \---WEB-INF
    |               web.xml
    |
    \---test
        \---java

Build it, use the jar as a dependency in your project, and you're done. This will permanently release you from the big pain-in-the-butt that GWT calls "widgetset compilation".