1. groovyc, the Groovy compiler

groovyc is the Groovy compiler command line tool. It allows you to compile Groovy sources into bytecode. It plays the same role as javac in the Java world. The easiest way to compile a Groovy script or class is to run the following command:

groovyc MyClass.groovy

This will produce a MyClass.class file (as well as other .class files depending on the contents of the source). groovyc supports a number of command line switches:

Short version Long version Description Example

@argfile

Read options and source files from specified file.

groovyc @conf/args

-cp

-classpath, --classpath

Specify the compilation classpath. Must be the first argument.

groovyc -cp lib/dep.jar MyClass.groovy

--sourcepath

Directory where to find source files. Not used anymore. Specifying this parameter will have no effect.

--temp

Temporary directory for the compiler

--encoding

Encoding of the source files

groovyc --encoding utf-8 script.groovy

--help

Displays help for the command line groovyc tool

groovyc --help

-d

Specify where to place generated class files.

groovyc -d target Person.groovy

-v

--version

Displays the compiler version

groovyc -v

-e

--exception

Displays the stack trace in case of compilation error

groovyc -e script.groovy

-j

--jointCompilation*

Enables joint compilation

groovyc -j A.groovy B.java

-b

--basescript

Base class name for scripts (must derive from Script)

-indy

--indy

Enables invokedynamic support. Requires Java 7+

groovyc --indy Person.groovy

--configscript

Advanced compiler configuration script

groovyc --configscript config/config.groovy src/Person.groovy

-Jproperty=value

Properties to be passed to javac if joint compilation is enabled

groovyc -j -Jtarget=1.6 -Jsource=1.6 A.groovy B.java

-Fflag

Flags to be passed to javac if joint compilation is enabled

groovyc -j -Fnowarn A.groovy B.java

Notes: * for a full description of joint compilation, see the joint compilation section.

2. Ant task

2.1. <groovyc>

2.1.1. Description

Compiles Groovy source files and, if joint compilation option is used, Java source files.

2.1.2. Required taskdef

Assuming groovy-all-VERSION.jar is in my.classpath you will need to declare this task at some point in the build.xml prior to the groovyc task being invoked.

<taskdef name="groovyc"
         classname="org.codehaus.groovy.ant.Groovyc"
         classpathref="my.classpath"/>

2.1.3. <groovyc> Attributes

Attribute Description Required

configscript

Set the configuration file used to customize the compilation configuration.

No

srcdir

Location of the Groovy (and possibly Java) source files.

Yes

destdir

Location to store the class files.

Yes

classpath

The classpath to use.

No

classpathref

The classpath to use given as a path references.

No

sourcepath

The sourcepath to use.

No

sourcepathref

The sourcepath to use given as a path reference.

No

encoding

Encoding of source files.

No

verbose

Asks the compiler for verbose output; defaults to no.

No

includeAntRuntime

Whether to include the Ant run-time libraries in the classpath; defaults to yes.

No

includeJavaRuntime

Whether to include the default run-time libraries from the executing VM in the classpath; defaults to no.

No

fork

Whether to execute groovyc using a spawned instance of the JVM; defaults to no.

No

memoryInitialSize

The initial size of the memory for the underlying VM, if using fork mode; ignored otherwise. Defaults to the standard VM memory setting. (Examples: 83886080, 81920k, or 80m)

No

memoryMaximumSize

The maximum size of the memory for the underlying VM, if using fork mode; ignored otherwise. Defaults to the standard VM memory setting. (Examples: 83886080, 81920k, or 80m)

No

failonerror

Indicates whether compilation errors will fail the build; defaults to true.

No

listfiles

Indicates whether the source files to be compiled will be listed; defaults to no.

No

stacktrace

if true each compile error message will contain a stacktrace

No

indy

Enable compilation with the ``invoke dynamic'' support when using Groovy 2.0 and beyond and running on JDK 7

No

scriptBaseClass

Sets the base class for Groovy scripts

No

stubdir

Set the stub directory into which the Java source stub files should be generated. The directory need not exist and will not be deleted automatically - though its contents will be cleared unless 'keepStubs' is true. Ignored when forked.

No

keepStubs

Set the keepStubs flag. Defaults to false. Set to true for debugging. Ignored when forked.

No

forceLookupUnnamedFiles

The Groovyc Ant task is frequently used in the context of a build system that knows the complete list of source files to be compiled. In such a context, it is wasteful for the Groovy compiler to go searching the classpath when looking for source files and hence by default the Groovyc Ant task calls the compiler in a special mode with such searching turned off. If you wish the compiler to search for source files then you need to set this flag to true. Defaults to false.

No

Example:

<groovyc srcdir="src" destdir="target/classes">
</groovyc>

2.1.4. <groovyc> Nested Elements

element kind Required Replaces Attribute

javac

javac task

No

jointCompilationOptions

src

a path structure

Yes (unless srcdir is used)

srcdir

classpath

a path structure

No

classpath

Notes:

  • For path structures see for example http://ant.apache.org/manual/using.html#path

  • For usages of the javac task see https://ant.apache.org/manual/Tasks/javac.html

  • The nested javac task behaves more or less as documented for the top-level javac task. srcdir, destdir, classpath, encoding for the nested javac task are taken from the enclosing groovyc task. If these attributes are specified then they are added, they do not replace. In fact, you should not attempt to overwrite the destination. Other attributes and nested elements are unaffected, for example fork, memoryMaximumSize, etc. may be used freely.

2.1.5. Joint Compilation

Joint compilation is enabled by using an embedded javac element, as shown in the following example:

<groovyc srcdir="${testSourceDirectory}" destdir="${testClassesDirectory}">
  <classpath>
    <pathelement path="${mainClassesDirectory}"/>
    <pathelement path="${testClassesDirectory}"/>
    <path refid="testPath"/>
  </classpath>
  <javac source="1.7" target="1.7" debug="on" />
</groovyc>

It is rare to specify srcdir and destdir, the nested javac task is provided with the srcdir and destdir values from the enclosing groovyc task, and it is invariable the right thing to do just to leave this as is. To restate: the javac task gets the srcdir, destdir and classpath from the enclosing groovyc task.

More details about joint compilation can be found in the joint compilation section.

3. Gant

Gant is a tool for scripting Ant tasks using Groovy instead of XML to specify the logic. As such, it has exactly the same features as the Groovyc Ant task.

4. Gradle

Gradle is a build tool that allows you to leverage the flexibility of Ant, while keeping the simplicity of convention over configuration that tools like Maven offer. Builds are specified using a Groovy DSL, which offers great flexibility and succinctness.

5. Maven integration

There are several approaches to compiling Groovy code in your Maven projects. GMavenPlus is the most flexible and feature rich, but like most Groovy compiler tools, it can have difficulties with joint Java-Groovy projects (for the same reason GMaven and Gradle can have issues). The Groovy-Eclipse compiler plugin for Maven sidesteps the joint compilation issues. Read this for a deeper discussion of the benefits and disadvantages of the two approaches.

A third approach is to use Maven’s Ant plugin to compile a groovy project. Note that the Ant plugin is bound to the compile and test-compile phases of the build in the example below. It will be invoked during these phases and the contained tasks will be carried out which runs the Groovy compiler over the source and test directories. The resulting Java classes will coexist with and be treated like any standard Java classes compiled from Java source and will appear no different to the JRE, or the JUnit runtime.

<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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.mycomp.MyGroovy</groupId>
    <artifactId>MyGroovy</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>Maven Example building a Groovy project</name>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy-all</artifactId>
            <version>2.1.6</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-antrun-plugin</artifactId>
                <executions>
                    <execution>
                        <id>compile</id>
                        <phase>compile</phase>
                        <configuration>
                            <tasks>
                                <mkdir dir="${basedir}/src/main/groovy"/>
                                <taskdef name="groovyc"
                                    classname="org.codehaus.groovy.ant.Groovyc">
                                    <classpath refid="maven.compile.classpath"/>
                                </taskdef>
                                <mkdir dir="${project.build.outputDirectory}"/>
                                <groovyc destdir="${project.build.outputDirectory}"
                                    srcdir="${basedir}/src/main/groovy/" listfiles="true">
                                    <classpath refid="maven.compile.classpath"/>
                                </groovyc>
                            </tasks>
                        </configuration>
                        <goals>
                            <goal>run</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>test-compile</id>
                        <phase>test-compile</phase>
                        <configuration>
                            <tasks>
                                <mkdir dir="${basedir}/src/test/groovy"/>
                                <taskdef name="groovyc"
                                    classname="org.codehaus.groovy.ant.Groovyc">
                                    <classpath refid="maven.test.classpath"/>
                                </taskdef>
                                <mkdir dir="${project.build.testOutputDirectory}"/>
                                <groovyc destdir="${project.build.testOutputDirectory}"
                                    srcdir="${basedir}/src/test/groovy/" listfiles="true">
                                    <classpath refid="maven.test.classpath"/>
                                </groovyc>
                            </tasks>
                        </configuration>
                        <goals>
                            <goal>run</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

This assumes you have a Maven project setup with groovy subfolders as peers to the java src and test subfolders. You can use the java/jar archetype to set this up then rename the java folders to groovy or keep the java folders and just create groovy peer folders. There exists, also a groovy plugin which has not been tested or used in production. After defining the build section as in the above example, you can invoke the typical Maven build phases normally. For example, mvn test will execute the test phase, compiling Groovy source and Groovy test source and finally executing the unit tests. If you run mvn jar it will execute the jar phase bundling up all of your compiled production classes into a jar after all of the unit tests pass. For more detail on Maven build phases consult the Maven2 documentation.

5.1. GMaven and GMavenPlus

5.1.1. GMaven

GMaven is the original Maven plugin for Groovy, supporting both compiling and scripting Groovy.

Important:

You should be aware that GMaven is not supported anymore and can have difficulties with joint compilation. GMavenPlus can be a good replacement, but if you are having problems with joint compilation, you might consider the Groovy Eclipse maven plugin.

5.1.2. GMavenPlus

GMavenPlus is a rewrite of GMaven and is in active development. It supports most of the features of GMaven (a couple notable exceptions being mojo Javadoc tags and support for older Groovy versions). Its joint compilation uses stubs (which means it has the same potential issues as GMaven and Gradle). The main advantages over its predecessor are that it supports recent Groovy versions, InvokeDynamic, Groovy on Android, GroovyDoc, and configuration scripts.

5.1.3. GMaven 2

Unlike the name might seem to suggest, GMaven 2 is not aimed at replacing GMaven. In fact, it removes the non-scripting features of the GMaven plugin. It has not yet had any release and appears to be inactive currently.

5.2. The Groovy Eclipse Maven plugin

Groovy-Eclipse provides a compiler plugin for Maven. Using the compiler plugin, it is possible to compile your maven projects using the Groovy-Eclipse compiler. One feature unavailable elsewhere is stubless joint compilation.

6. Joint compilation

Joint compilation means that the Groovy compiler will parse the Groovy source files, create stubs for all of them, invoke the Java compiler to compile the stubs along with Java sources, and then continue compilation in the normal Groovy compiler way. This allows mixing of Java and Groovy files without constraint.

Joint compilation can be enabled using the -j flag with the command-line compiler, or using using a nested tag and all the attributes and further nested tags as required for the Ant task.

It is important to know that if you don’t enable joint compilation and try to compile Java source files with the Groovy compiler, the Java source files will be compiled as if they were Groovy sources. In some situations, this might work since most of the Java syntax is compatible with Groovy, but semantics would be different.

7. Android support

It is possible to write an Android application in Groovy. However this requires a special version of the compiler, meaning that you cannot use the regular groovyc tool to target Android bytecode. In particular, Groovy provides specific JAR files for Android, which have a classifier of grooid. In order to make things easier, a Gradle plugin adds support for the Groovy language in the Android Gradle toolchain.

The plugin can be applied like this:

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.1.2'
        classpath 'org.codehaus.groovy:groovy-android-gradle-plugin:1.0.0'
    }
}

apply plugin: 'groovyx.android'

Then you will need to add a dependency on the grooid version of the Groovy compiler:

dependencies {
    compile 'org.codehaus.groovy:groovy:2.4.8:grooid'
}

Note that if a Groovy jar does not provide a grooid classifier alternative, then it means that the jar is directly compatible with Android. In that case, you can add the dependency directly like this:

dependencies {
    compile 'org.codehaus.groovy:groovy:2.4.8:grooid'       // requires the grooid classifier
    compile ('org.codehaus.groovy:groovy-json:2.4.8') {     // no grooid version available
        transitive = false                                  // so do not depend on non-grooid version
    }
}

Note that the transitive=false parameter for groovy-json will let Gradle download the JSON support jar without adding a dependency onto the normal jar of Groovy.

Please make sure to go to the plugin homepage in order to find the latest documentation and version.