Skip to main content

Compile the Vaadin Widgetset with Grails

With "regular" Java, compiling of the WidgetSet is done using a Maven target. This is not possible with Grails directly. The Vaadin Wiki explains how it is done, but depends on setting the classpath proplerly.

So here is how I do it:

Set the name of your WidgetSet in grails-app/conf/VaadinConfig.groovy; there should already be a comment

vaadin {
  // ...
  widgetset = 'net.ofnir.project.widgetset'
  // ...
}

Create a Widgetset. E.g.: src/java/net/ofnir/project/widgetset.gwt.xml

<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.0//EN" "http://google-web-toolkit.googlecode.com/svn/releases/2.0/distro-source/core/src/gwt-module.dtd">
<module>
    <inherits name="org.vaadin.openesignforms.ckeditor.widgetset.VaadinCKEditorWidgetset"/>
    <inherits name="org.vaadin.tokenfield.TokenfieldWidgetset" />
</module>

Be sure to add the repos needed for your modules and the vaadin-client-compiler. E.g. grails-app/conf/BuildConfig.groovy

repositories {
    // ...
    mavenRepo "http://oss.sonatype.org/content/repositories/vaadin-releases"
    mavenRepo 'http://maven.vaadin.com/vaadin-addons'
    // ...
}

dependencies {
    // ...
    compile "com.vaadin:vaadin-client-compiler:${vaadinVersion}"
    compile 'org.vaadin.addons:ckeditor-wrapper-for-vaadin:7.8.3'
    compile 'org.vaadin.addons:tokenfield:7.0.1'
    // ...
}

Create scripts/VaadinCompile.groovy

includeTargets << grailsScript("_GrailsInit")
includeTargets << grailsScript("_GrailsClasspath")
includeTargets << grailsScript("_GrailsRun")

target(widgetset_init: "init") {
    vaadinConfig = new ConfigSlurper(grails.util.Environment.current.name).parse(new File("${basedir}/grails-app/conf/VaadinConfig.groovy").text)
    ant.property(name: "widgetset", value: vaadinConfig.vaadin.widgetset)
    ant.property(name: "workers", value: "4")
    ant.property(name: "widgetset-path", value: "")
    ant.property(name: "client-side-destination", value: "web-app/VAADIN/widgetsets")
    ant.property(name: "generate.widgetset", value: "1")
}

target(compile_widgetset: "widgetset") {
    depends(classpath, compile, widgetset_init)
    ant.echo message: """Compiling ${ant.project.properties.'widgetset'} into ${ant.project.properties."client-side-destination"} directory..."""
    ant.java(classname: "com.google.gwt.dev.Compiler", maxmemory: "512m", failonerror: true, fork: true, classpathref: "grails.compile.classpath") {
        ant.classpath {
            pathelement location: "${basedir}/src/java"
            pathelement location: "${basedir}/target/classes"
        }
        arg(value: "-localWorkers")
        arg(value: "${ant.project.properties.'workers'}")
        arg(value: "-war")
        arg(value: ant.project.properties.'client-side-destination')
        arg(value: ant.project.properties.'widgetset')
        jvmarg(value: "-Xss1024k")
        jvmarg(value: "-Djava.awt.headless=true")
    }
}

setDefaultTarget(compile_widgetset)

And finally you can build your Widgetset with

grails vaadin-compile

If you are rolling a WAR file and want to be sure, to have it as slim as possible, add some clean up code to scripts/_Events.groovy

eventCreateWarStart = { name, stagingDir ->
    new File("${stagingDir}/VAADIN/gwt-unitCache").deleteDir()
    ant.delete(dir:"${stagingDir}/WEB-INF/lib/", includes: "vaadin-client-compiler-*.*.*.jar", verbose: true)
    ant.delete(dir:"${stagingDir}/WEB-INF/lib/", includes: "vaadin-theme-compiler-*.*.*.jar", verbose: true)
}