2009-09-25

Using Gradle to deploy to Glassfish

As mentioned before, I've used Gradle for my build in my latest project. I started to get tired of logging on to the admin console to deploy the WAR file so it was time to look at Glassfish & Gradle in combination.

Glassfish 2.1 includes some ANT tasks which is a wrapper to the asadmin command line tools. Using ANT tasks from Gradle is really simple - even those who aren't part of the main ANT distribution.

I started out with checking if the machine has an environment variable pointing to the glassfish install directory:

gfHome = System.getenv('GLASSFISH_HOME')
logger.info("Glassfish home: " + gfHome)
if (gfHome == null || gfHome.length() <= 0)
{
msg = "No GLASSFISH_HOME in environment variable. Please set GLASSFISH_HOME to glassfish installation directory"
logger.error(msg)
throw new RuntimeException(msg)
}
This will throw an error and the build script will fail if the environment variable GLASSFISH_HOME isn't set. If this succeeds I need to define the task by using ANT's taskdef from Gradle.

ant.taskdef(name: 'gfDeploy',
classname: 'org.apache.tools.ant.taskdefs.optional.sun.appserv.DeployTask') {
classpath {
fileset(dir: gfHome + File.separator + 'lib') {
include(name: '*.jar')
}
}
}
I use the lib directory of the Glassfish install directory and add all jar files to the classpath.

In order to use the deploy task, I need a password file which contains the password for the admin user. I've added a file called dev.passfile in the project directory and it contains a singel line:

AS_ADMIN_PASSWORD=adminadmin
Then the only thing which is missing is calling the task:

ant.gfdeploy(file: war.archivePath.path, name: project.name, contextroot: project.name,
upload: 'true', precompilejsp: 'false', asinstalldir: gfHome) {
server(host: 'mydevserver', port: '40048', user: 'admin', passwordfile: 'dev.passfile')
}
As you see I can reference the war file with the war.archivePath.path. This is a handy shortcut to reference the generated WAR file. Also used the project.name as the context root which avoids the version number in the URL.

Since I need to define an undeploy tasks also I can use the power of Groovy and separate out the commen part as a method. For instance I need to check for GLASSFISH_HOME environment variable for each task I define so I put this in a separate method:

def getGlassfishHomeDir()
{
gfHome = System.getenv('GLASSFISH_HOME')
logger.info("Glassfish home: " + gfHome)
if (gfHome == null || gfHome.length() <= 0)
{
msg = "No GLASSFISH_HOME in environment variable. Please set GLASSFISH_HOME to glassfish installation directory"
logger.error(msg)
throw new RuntimeException(msg)
}
return gfHome
}
This can then be called from every gradle tasks.

Smooth :-)