Abstract
The script GroovyWrapper described on this page, creates a self-excutable jar from a groovy script.
Description
The script GroovyWrapper allows you to distribute your groovy script as a standalone self-executable jar.
The generated jar contains the compiled groovy script, and the groovy embeddable jar. Moreover the jar's main-class is set to the compiled groovy script.
Having this self-executable jar, you can start the groovy script, like java -jar MyScriptAsJar.jar
Groovy Wrapper Script
The Groovy Wrapper Script below is quite simple.
First it parses its command line arguments using groovy's CliBuilder.
- The argument
-mdefines the groovy script name, w/o {{.class} suffix - The optional argument
-dallows defines the jar fileame, by default the jar filename is build as {{
groovy-script-name.jar}}. - The argument
-ccompile the groovy script in the GroovyWrapper. Use this argument if your groovy script is not compiled by some build process.
Next if checks the arguments, compiles the script if specified.
Then the environment variable GROOVY_HOME is looked up for calculating the file location of the groovy embeddable jar.
Finnally GroovyWrapper builds the jar using AntBuilder.
The source of the GroovyWrapper script:
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Wrap a script and groovy jars to an executable jar
*/
def cli = new CliBuilder()
cli.h( longOpt: 'help', required: false, 'show usage information' )
cli.d( longOpt: 'destfile', argName: 'destfile', required: false, args: 1, 'jar destintation filename, defaults to {mainclass}.jar' )
cli.m( longOpt: 'mainclass', argName: 'mainclass', required: true, args: 1, 'fully qualified main class, eg. HelloWorld' )
cli.c( longOpt: 'groovyc', required: false, 'Run groovyc' )
//--------------------------------------------------------------------------
def opt = cli.parse(args)
if (!opt) { return }
if (opt.h) {
cli.usage();
return
}
def mainClass = opt.m
def scriptBase = mainClass.replace( '.', '/' )
def scriptFile = new File( scriptBase + '.groovy' )
if (!scriptFile.canRead()) {
println "Cannot read script file: '${scriptFile}'"
return
}
def destFile = scriptBase + '.jar'
if (opt.d) {
destFile = opt.d
}
//--------------------------------------------------------------------------
def ant = new AntBuilder()
if (opt.c) {
ant.echo( "Compiling ${scriptFile}" )
org.codehaus.groovy.tools.FileSystemCompiler.main( [ scriptFile ] as String[] )
}
def GROOVY_HOME = new File( System.getenv('GROOVY_HOME') )
if (!GROOVY_HOME.canRead()) {
ant.echo( "Missing environment variable GROOVY_HOME: '${GROOVY_HOME}'" )
return
}
ant.jar( destfile: destFile, compress: true, index: true ) {
fileset( dir: '.', includes: scriptBase + '*.class' )
zipgroupfileset( dir: GROOVY_HOME, includes: 'embeddable/groovy-all-*.jar' )
zipgroupfileset( dir: GROOVY_HOME, includes: 'lib/commons*.jar' )
// add more jars here
manifest {
attribute( name: 'Main-Class', value: mainClass )
}
}
ant.echo( "Run script using: \'java -jar ${destFile} ...\'" )
Example
An example for using GroovyWrapper:
Say you have groovy script HelloWorld.groovy, use GroovyWrapper for building HelloWorld.jar, as follows:
$ groovy GroovyWrapper -c -m HelloWorld
GroovyWrapper will compile the script HelloWorld.groovy to HelloWorld.class, and creates a self-executable jar HelloWorld.jar.
Now you can use the HelloWorld.jar for launching the HelloWorld script, simply by running:
$ java -jar HelloWorld.jar
3 Comments
Hide/Show CommentsApr 01, 2009
Dany Poupard
Just a little patch to make GroovyWrapper Java 1.4 compatible.
Indeed, in Java 1.4, "System.getenv()" is deprecated, so, if you need to use this java version, then apply the patch below :
// ** BEGIN : PATCH FOR JAVA 1.4 **
// Old code :
// def GROOVY_HOME = new File( System.getenv('GROOVY_HOME') )
// New code :
if (System.getProperty("java.version").startsWith("1.4")) {
GROOVY_HOME = new File( System.getProperty('groovy.home') )
} else {
GROOVY_HOME = new File( System.getenv('GROOVY_HOME') )
}
// ** END : PATCH FOR JAVA 1.4 **
Jul 28, 2011
Nick Dunlop
The logic around checking GROOVY_HOME is not quite right. If the GROOVY_HOME environment variable is not set the script explodes with a NullPointerException.
Should probably check its existence before trying to use it in new File( ... ). Also means that if the variable is set but unreadable then the error message is a little misleading.
Jun 29, 2012
Andreas Rehn
Good script, just what I was looking for. I did som enhancements that allows for bundling all grape dependencis in jar. Jar can then be executed with java -Dgroovy.grape.enable=false -jar <destfile>.jar. The following was added:
grapes.each() { grape ->def grapeFile = new File(grape)
if (grapeFile.exists()) {
zipgroupfileset(dir: grapeFile.parent, includes: grapeFile.name)
}
}