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

4

14

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

Inebriant answered 8/1, 2014 at 19:55 Comment(5)
Did you use Vaadin Plug-in for Eclipse to generate maven project with this pom?Then
@Then I created the project with mvn archetype:generate ... I thought Eclipse Vaadin Plugin didn't allow to create maven projectsInebriant
Ok, I checked - I created it through eclipse, maven project with vaadin7 artifact, and then widgetset does not get compiled.Then
@Then Could you please answer the question and explain the procedure you followed to create the project so the community can benefit from it? ThanksInebriant
@Then I double checked and vaadin eclipse plugin at least the current version 2.2.0.201312051010 doesn't have the option for creating a maven project, it uses Ivy as dependency management tool. If you use the maven artifact as I show in the question post it will compile the widgets every time if you run the maven with the install goal: mvn installInebriant
R
22

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".

Remanent answered 15/1, 2014 at 1:23 Comment(1)
I like this approach you suggest as it isolates the widgetset and allows me to decide when to compile the widgetset or not. Also it seems that with this approach it is possible to reuse or share the widgetset between different vaadin applications that just include this project as a dependency, that way the addons that I can add in the future will be accessible to all the projects like a library. I will try to implement it, thanks.Inebriant
R
3

To reduce the compile time of the widgetset you could and following to the .gwt.xml file and uncomment the set-property tag.

<!-- Uncomment the following to compile the widgetset for one browser only. 
    This can reduce the GWT compilation time significantly when debugging. The 
    line should be commented out before deployment to production environments. 
    Multiple browsers can be specified for GWT 1.7 as a comma separated list. 
    The supported user agents at the moment of writing were:   ie6,ie8,gecko,gecko1_8,safari,opera 
    The value gecko1_8 is used for Firefox 3 and later and safari is used for 
    webkit based browsers including Google Chrome. -->
<!-- <set-property name="user.agent" value="gecko1_8"/> -->

to create a new vaadin-maven project, you could try use the vaadin 7 plugin new project wizard which will create a new project with ivy dependency management, after creating the project, right click on the project and remove ivy dependency management, and then right click --> configure--> convert it to maven project will add maven dependency management to the project.

Resentful answered 9/1, 2014 at 9:14 Comment(3)
@Supun_Sameera I did what you said, but it creates an empty maven pom.xml file and the build fails, so it would require some work in configuration in order to add all the dependencies and plugins necessary for maven knowing how to build this kind of project. So I don't think this is the right solution for the problem as I may ending up with the same configuration than the one mvn archetype generated and therefore with the same issue on widget compilation.Inebriant
I do not understand the second part of this answer. But the first part works for me. Edit the AppWidgetSet.gwt.xml file found with your main Vaadin .java files. Copy that commented line seen above. Substitute for the browser type you use during development. For example on a Mac using Safari (and apparently Chrome) for debugging from the IDE (such as NetBeans), use <set-property name="user.agent" value="safari"/>. This reduces the very lengthy compile times for 6 "permutations" to only 1 "permutation".Bein
@SupunSameera Did you bundle two separate answers into one posting? If so, please separate them by making a second Answer posting. If not, please clarify your 2nd half.Bein
A
1

Just dont compile any widget, use the default one; for that you must set the following files: web.xml:

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

Or in the UI implementation for your project:

/**
 * Initial view in Vaadin
 */
@Theme("valo") 
@Widgetset("com.vaadin.DefaultWidgetSet")
public class MainUI extends UI
{

Finally in the pom.xml include just these dependencies:

    <!-- Vaadin dependencies -->
    <dependency>
        <groupId>com.vaadin</groupId>
        <artifactId>vaadin-server</artifactId>
        <version>${vaadin.version}</version>
    </dependency> 
    <dependency>
        <groupId>com.vaadin</groupId>
        <artifactId>vaadin-client-compiled</artifactId>
        <version>${vaadin.version}</version> 
    </dependency>   
    <dependency>
        <groupId>com.vaadin</groupId>
        <artifactId>vaadin-themes</artifactId>
        <version>${vaadin.version}</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.0.1</version> 
    </dependency> 

Nothing else. I solved with these, i hope you too.

Animal answered 5/4, 2015 at 22:6 Comment(0)
I
0

If you tired with constant compiling/recompiling widgetsets, I suggest you to use "CDN Viritin Magic"

Benefits:

  1. No @Widgetset
  2. no need in maven-vaadin-plugin
  3. Decreases compilation time in N-times.

Note 1 (for Vaadin Spring Boot users) :
After successful tutorial walkthrough(do not run mvn clean install yet!)
You have to define one more thing in YourAppNameApplication class :

@Bean
public in.virit.WidgetSet viritinCdnInitializer() {
    return new in.virit.WidgetSet();
}

Note 2: It's OK to use alongside with spring-boot-maven-plugin

Isolda answered 8/1, 2017 at 21:28 Comment(2)
Or if you are using 7.7.x or later, use the official CDN. Just add a property in your pom.xml like this: <vaadin.widgetset.mode>cdn</vaadin.widgetset.mode>Opine
@AlejandroDuarte Thank you very much for suggestion, didn't knew that. But if i'm a person, who doesn't like way too much xml's... where and how should i specify this option?Isolda

© 2022 - 2024 — McMap. All rights reserved.