Thursday, 27 December 2012

GWT with gradle wrapper

The Gradle Wrapper is the preferred way of starting a Gradle build. The wrapper is a shell script for linux. Starting a Gradle build via the wrapper, will automatically download Gradle.

[STEP 0] create the base folder structure
The architecture of my gwt-app is
prayag@Prayag:~/eccount$ ls -l
total 39
drwxrwxr-x 7 prayag prayag 4096 Dec 20 17:28 eccount-rpc
drwxrwxr-x 6 prayag prayag 4096 Dec 20 17:28 eccount-view
drwxrwxr-x 7 prayag prayag 4096 Dec 20 17:28 eccount-model
drwxrwxr-x 7 prayag prayag 4096 Dec 20 17:48 eccount-controller


[STEP 1] vi settings.gradle
include 'eccount-rpc','eccount-model','eccount-view','eccount-controller'


[STEP 2] : vi build.gradle file for the app with subprojects
The repositories{} in the buildScript{} block are used to fetch the dependencies{} of buildScript dependencies put on the classpath of build.

Configuration inside the subprojects{} block is used in every sub-project, for example fp-java meaning all of the sub-projects will compile java code.

base plugin adds the standard lifecycle tasks and configures reasonable defaults for the archive tasks.

description = 'eccount'

ext.springVersion = '3.1.0.RELEASE'

ext.springSecurityVersion = '3.1.0.RELEASE'
ext.gwtVersion = '2.4.0'
ext.springDataJpaVersion = '1.0.0.RELEASE'
ext.springSecurityVersion = '3.1.0.RELEASE'
ext.slf4jVersion = '1.5.6'
ext.logbackClassickVersion = '1.0.6'
ext.springWsVersion = '2.0.3.RELEASE'
ext.springBatchVersion = '2.1.8.RELEASE'
ext.tomcatWebappDir = 'Z:/docs/'
ext.artifactId = 'eccount'

version = '1.0'




buildscript {

ext.zcGradleVersion = '1.1.10'

def remoteMvnRepo = "http://zz.yy.xxx.rrr:8080/artifactory/repo" def remoteIvyRepo = "http://zz.yy.xxx.rrr:8080/artifactory/libs-releases-local"


 repositories {
ivy {
url remoteIvyRepo
layout 'maven'
}

maven {
url remoteMvnRepo

}

    }
    dependencies {
        classpath group: 'com.zazzercode.gradle', name: 'zcgradle', version: zcGradleVersion
classpath group: 'cc.catalysts', name: 'catalysts-gradle-plugins', version: 1.0
    }
}

apply plugin: 'zc'

apply plugin: 'sonar'

sonar {

    server {
        url = "http://zz.yy.xxx.r:9000/"
    }
    database {
        url = "jdbc:mysql://zz.yy.xxx.s:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true"
        driverClassName = "com.mysql.jdbc.Driver"
        username = "eccount"
        password = "eccount"
    }
}

sonar.project.name = "eccount"


 

 
/**
  * use the gradle deploy command with specifying at least one   configuration(eg eccountDeployToTomcat)
  */ deploy {
eccountDeployToTomcat {
type = 'lancopy'  // lancopy -> stops specified running tomcat service, copy the artifacts and then starts the tomcat service

tomcatHost = '' //localhost
tomcatService = 'EccountServer'
webappWar = '/eccount-controller/build/libs/ROOT.war'
webappDir = '/usr/local/apache-tomcat-7.0.42/webapps'
}

}


subprojects {
apply plugin: 'base'
apply plugin: 'eclipse-wtp'
apply plugin: 'idea'
apply plugin: 'zc-java'
 
   repositories {
maven {
url 'http://zz.yy.xxx.rrr:8080/artifactory/repo'
}
   
}

   dependencies {

        testCompile 'junit:junit:4.8.2'
   }

   jar {

        manifest.attributes provider: 'gradle'
   }

task testJar(type: Jar, dependsOn: testClasses) {
baseName = "test-${project.archivesBaseName}"
from sourceSets.test.output
from sourceSets.main.output
}

configurations {

tests
}
artifacts {
tests testJar
}
   sonar {
        project {
            coberturaReportPath = file("$buildDir/reports/cobertura/coverage.xml")
        }
    }
}



[STEP 3] : vi build.gradle for submodules
[3.1] vi build.gradle for eccount-view
description 'eccount view'

apply plugin: 'cat-gwt'


dependencies {

gwtCompile project(path: ':eccount-rpc', configuration: 'gwtCompile')

gwtCompile 'com.google.gwt:gwt-user:' + gwtVersion


gwtCompile 'com.google.gwt.inject:gin:1.5.0'
gwtCompile 'com.gwtplatform:gwtp-mvp-client:0.6'
gwtCompile 'com.gwtplatform:gwtp-clients-common:0.6'
gwtCompile 'com.gwtplatform:gwtp-processors:0.6'
gwtCompile 'com.google.inject:guice:3.0'
gwtCompile 'com.google.inject.extensions:guice-assistedinject:3.0'
gwtCompile 'javax.inject:javax.inject:1'
gwtCompile 'aopalliance:aopalliance:1.0'
gwtCompile 'com.googlecode.gwtquery.bundles:gquery-dnd-bundle:1.0.5'

testCompile 'junit:junit:4.8.2'

}


[3.2] vi build.gradle for eccount-rpc
description 'eccount rpc'
apply plugin: 'cat-gwt'
apply plugin: 'cat-codegen-java'

dependencies {


compile 'com.google.gwt:gwt-servlet:' + gwtVersion
compile group: 'javax.validation', name: 'validation-api', version: '1.0.0.GA', classifier: ''
}

codegenjava {

build {
packageName 'com.z.e.shared'
}
}



[3.3] vi build.gradle for eccount-model

A Configuration represents a group of artifacts and their dependencies.

Configuration exclude adds an exclude rule to exclude transitive dependencies for all dependencies of this configuration. exclude rules per-dependency can also be added . See ModuleDependency.exclude().


description 'ecount core'

configurations {

all*.exclude module: 'commons-logging'
all*.exclude module: 'log4j'
all*.exclude module: 'icu4j'
all*.exclude module: 'catalina'

}



dependencies {

compile project(':eccount-rpc')


compile 'org.springframework:spring-beans:' + springVersion
compile 'org.springframework:spring-core:' + springVersion
compile 'org.springframework:spring-orm:' + springVersion
compile 'org.springframework:spring-context:' + springVersion
compile 'org.springframework:spring-web:' + springVersion
compile 'org.springframework:spring-webmvc:' + springVersion
compile 'org.springframework:spring-aop:' + springVersion
compile 'org.springframework:spring-oxm:' + springVersion

compile 'org.springframework.security:spring-security-core:' + springSecurityVersion
compile 'org.springframework.security:spring-security-web:' + springSecurityVersion
compile 'org.springframework.security:spring-security-config:' + springSecurityVersion
compile 'javax.annotation:jsr250-api:1.0'

compile 'org.springframework.data:spring-data-jpa:' + springDataJpaVersion

compile 'org.springframework.batch:spring-batch-core:' + springBatchVersion
compile 'org.springframework.batch:spring-batch-infrastructure:' + springBatchVersion



compile 'commons-httpclient:commons-httpclient:3.1'
compile 'commons-codec:commons-codec:1.6'
compile 'org.apache.poi:poi:3.7'
compile 'commons-net:commons-net:3.1'
compile 'commons-io:commons-io:1.4'
compile 'commons-dbcp:commons-dbcp:20030825.184428'
compile 'commons-pool:commons-pool:20030825.183949'


providedCompile 'javax.servlet:servlet-api:2.5'

compile 'org.apache.velocity:velocity:1.7'
compile 'javax.mail:mail:1.4.4'
compile 'com.lowagie:itext:2.0.7'

compile 'org.hibernate:hibernate-validator:4.0.0.GA'
compile 'org.hibernate:hibernate-entitymanager:3.6.6.Final'
compile 'org.hibernate.javax.persistence:hibernate-jpa-2.0-api:1.0.0.Final'
compile 'hsqldb:hsqldb:1.8.0.10'
compile 'c3p0:c3p0:0.9.1.2'

compile 'com.octo.captcha:jcaptcha:2.0-alpha-1'

compile 'ch.qos.logback:logback-classic:' + logbackClassickVersion

compile 'org.springframework.ws:spring-ws-core:' + springWsVersion
compile 'org.springframework.ws:spring-ws-security:' + springWsVersion
compile 'org.springframework.ws:spring-xml:' + springWsVersion
compile 'aopalliance:aopalliance:1.0'

compile 'jdom:jdom:1.0'
compile 'jaxen:jaxen:1.1'
compile 'xerces:xercesImpl:2.9.1'
compile 'xalan:xalan:2.7.1'
compile 'org.apache.ws.security:wss4j:1.6.4'
compile 'com.sun.xml.ws:webservices-rt:2.0.1'
compile 'xml-security:xmlsec:1.3.0'
compile 'xfire:opensaml:1.0.1'

testCompile 'junit:junit:4.8.2'
testCompile 'org.springframework:spring-test:' + springVersion
testCompile 'org.mockito:mockito-core:1.9.0'
testCompile 'org.springframework.ws:spring-ws-test:' + springWsVersion
testCompile 'org.springframework.batch:spring-batch-test:' + springBatchVersion

testRuntime 'javax.servlet:servlet-api:2.5'
testRuntime 'org.springframework.security:spring-security-core:' + springSecurityVersion
testRuntime 'org.springframework.security:spring-security-web:' + springSecurityVersion
testRuntime 'org.springframework.security:spring-security-config:' + springSecurityVersion

runtime 'mysql:mysql-connector-java:5.1.18'


}


[STEP 4] : The gradlew script,
with CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
is :


#!/bin/bash

##############################################################################

##
##  Gradle start up script for UN*X
##
##############################################################################

# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.

DEFAULT_JVM_OPTS="-Xmx1024m -XX:MaxPermSize=512m -Dfile.encoding=UTF-8"

APP_NAME="Gradle"

APP_BASE_NAME=`basename "$0"`

# Use the maximum available, or set MAX_FD != -1 to use that value.

MAX_FD="maximum"

warn ( ) {

    echo "$*"
}

die ( ) {

    echo
    echo "$*"
    echo
    exit 1
}

# OS specific support (must be 'true' or 'false').

cygwin=false
msys=false
darwin=false
case "`uname`" in
  CYGWIN* )
    cygwin=true
    ;;
  Darwin* )
    darwin=true
    ;;
  MINGW* )
    msys=true
    ;;
esac

# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
    [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi

# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
    ls=`ls -ld "$PRG"`
    link=`expr "$ls" : '.*-> \(.*\)$'`
    if expr "$link" : '/.*' > /dev/null; then
        PRG="$link"
    else
        PRG=`dirname "$PRG"`"/$link"
    fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/"
APP_HOME="`pwd -P`"
cd "$SAVED"

CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar

# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
        # IBM's JDK on AIX uses strange locations for the executables
        JAVACMD="$JAVA_HOME/jre/sh/java"
    else
        JAVACMD="$JAVA_HOME/bin/java"
    fi
    if [ ! -x "$JAVACMD" ] ; then
        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
    fi
else
    JAVACMD="java"
    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi

# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
    MAX_FD_LIMIT=`ulimit -H -n`
    if [ $? -eq 0 ] ; then
        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
            MAX_FD="$MAX_FD_LIMIT"
        fi
        ulimit -n $MAX_FD
        if [ $? -ne 0 ] ; then
            warn "Could not set maximum file descriptor limit: $MAX_FD"
        fi
    else
        warn "Could not query businessSystem maximum file descriptor limit: $MAX_FD_LIMIT"
    fi
fi

# For Darwin, add APP_NAME to the JAVA_OPTS as -Xdock:name
if $darwin; then
    JAVA_OPTS="$JAVA_OPTS -Xdock:name=$APP_NAME"
# we may also want to set -Xdock:image
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`

    # We build the pattern for arguments to be converted via cygpath
    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
    SEP=""
    for dir in $ROOTDIRSRAW ; do
        ROOTDIRS="$ROOTDIRS$SEP$dir"
        SEP="|"
    done
    OURCYGPATTERN="(^($ROOTDIRS))"
    # Add a user-defined pattern to the cygpath arguments
    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
    fi
    # Now convert the arguments - kludge to limit ourselves to /bin/sh
    i=0
    for arg in "$@" ; do
        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option

        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
        else
            eval `echo args$i`="\"$arg\""
        fi
        i=$((i+1))
    done
    case $i in
        (0) set -- ;;
        (1) set -- "$args0" ;;
        (2) set -- "$args0" "$args1" ;;
        (3) set -- "$args0" "$args1" "$args2" ;;
        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
    esac
fi

# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
    JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"

exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"




The gradlw tasks are (similar to  scala ./sbt tasks) :

prayag@Prayag:~/eccount$ ./gradlew tasks
:tasks

------------------------------------------------------------

All tasks runnable from root project - E
------------------------------------------------------------

Build tasks

-----------
assemble - Assembles all Jar, War, Zip, and Tar archives.
build - Assembles and tests this project.
buildDependents - Assembles and tests this project and all projects that depend on it.
buildNeeded - Assembles and tests this project and all projects it depends on.
classes - Assembles the main classes.
clean - Deletes the build directory.
jar - Assembles a jar archive containing the main classes.
testClasses - Assembles the test classes.
war - Generates a war archive with all the compiled classes, the web-app content and the libraries.

Documentation tasks

-------------------
javadoc - Generates Javadoc API documentation for the main source code.

Gwt tasks

---------
cleanGwt
compileGwt
generateLaunchConfig

Help tasks

----------
dependencies - Displays the dependencies of root project 'e-hg'.
help - Displays a help message
projects - Displays the sub-projects of root project 'e-hg'.
properties - Displays the properties of root project 'e-hg'.
tasks - Displays the tasks runnable from root project 'e-hg' (some of the displayed tasks may belong to subprojects).

IDE tasks

---------
cleanEclipse - Cleans all Eclipse files.
cleanEclipseWtp - Cleans Eclipse wtp configuration files.
cleanIdea - Cleans IDEA project files (IML, IPR)
eclipse - Generates all Eclipse files.
eclipseWtp - Generates Eclipse wtp configuration files.
idea - Generates IDEA project files (IML, IPR, IWS)

Report tasks

------------
cobertura - Generate Cobertura code coverage report

Upload tasks

------------
uploadArchives - Uploads all artifacts belonging to configuration ':e-api:archives'

Verification tasks

------------------
check - Runs all checks.
test - Runs the unit tests.

Other tasks

-----------
cleanBuildinfo
codegen
compile
deploy
sonarAnalyze
testJar
wrapper

To see all tasks and more detail, run with --all.


BUILD SUCCESSFUL


Total time: 6.311 secs



[STEP 5] The final app structure

prayag@Prayag:~/eccount$ ls -l
total 48
-rw-rw-r-- 1 prayag prayag 2292 Dec 20 17:11 build.gradle
drwxrwxr-x 7 prayag prayag 4096 Dec 20 17:28 eccount-rpc
drwxrwxr-x 6 prayag prayag 4096 Dec 20 17:28 eccount-view
drwxrwxr-x 7 prayag prayag 4096 Dec 20 17:28 eccount-model
drwxrwxr-x 7 prayag prayag 4096 Dec 20 17:48 eccount-controller
drwxrwxr-x 3 prayag prayag 4096 Dec 20 17:11 gradle
-rwxrwxr-x 1 prayag prayag 5048 Dec 21 14:39 gradlew
-rw-rw-r-- 1 prayag prayag 2404 Dec 20 17:11 gradlew.bat
-rw-rw-r-- 1 prayag prayag   79 Dec 20 17:11 settings.gradle


[STEP 6] : eclipsify the project
prayag@Prayag:~/eccount$./gradlew eclipse -q

Look at Appendix D. Gradle Command Line for more options(like -q) with gradlew command.

[STEP 7] : build the project
prayag@Prayag:~/eccount$ ./gradlew build -q
[...]
cat-gwt: Compiling admin with GWT 2.4.0 using the following jars:
    gwt-user-2.4.0.jar
    validation-api-1.0.0.GA-sources.jar
    validation-api-1.0.0.GA.jar
    gwt-dev-2.4.0.jar
    es-gwt-1.0-SNAPSHOT.jar
    e-api-1.0-SNAPSHOT.jar
    javax.inject-1.jar
    aopalliance-1.0.jar
    asm-3.1.jar
    cglib-2.2.1-v20090111.jar
    guice-3.0.jar
    guice-assistedinject-3.0.jar
    gwt-servlet-2.2.0.jar
    gin-1.5.0.jar
    gwtp-clients-common-0.6.jar
    gwtp-mvp-client-0.6.jar
    gwtp-processors-0.6.jar
    gquery-dnd-bundle-1.0.5.jar
Compiling module com.e.eAdmin
   Validating newly compiled units
      Ignored 6 units with compilation errors in first pass.
Compile with -strict or with -logLevel set to TRACE or DEBUG to see all errors.
   Scanning for additional dependencies: jar:file:...............
[...]
   Compiling 12 permutations
      Compiling permutation 0...
      Compiling permutation 1...
      Compiling permutation 2...
      Compiling permutation 3...
      Compiling permutation 4...
      Compiling permutation 5...
> Building > :e-server:compileGwt
[...]


If you don't want test cases to run
prayag@Prayag:~/eccount$ ./gradlew build -x test

To view dependency tree
prayag@Prayag:~/eccount$ ./gradlew -q dependencies eccount-core:dependencies
OR
prayag@Prayag:~/eccount$ ./gradlew -q eccount-core:dependencies

References
[1] My first steps with Gradle: creating a multi module java web project and running it with jetty, jettro, on September 8th, 2010,
http://www.gridshore.nl/2010/09/08/my-first-steps-with-gradle-creating-a-multi-module-java-web-project-and-running-it-with-jetty/

[2] Spring MVC project with Gradle,
http://blog.codeminimus.com/post/15443962161/spring-mvc-project-with-gradle

[3] https://github.com/Catalysts/catalysts-gradle-plugins

[4] http://www.eveoh.nl/en/2012/01/using-google-web-toolkit-with-gradle/

[5] Appendix D. Gradle Command Line, http://www.gradle.org/docs/current/userguide/gradle_command_line.html

http://stackoverflow.com/a/12289926/432903

No comments:

Post a Comment