Wednesday, July 2, 2014

Apache Ant vs Gradle : The javac Task

Suppose you had the following HelloWorld.java file:
public class HelloWorld {

   public static void main(String[] args) {
      System.out.println("Hello World");
   }
}
To compile this simple application in Apache Ant you use the javac task:
<?xml version="1.0"?>
<project>
    <javac srcdir = "." includes = "HelloWorld.java" includeAntRuntime = "false" />
</project>
Concerning the includeAntRuntime, I found this this quote in the Ant developer forums by a user named Chet Hosey:
“Historically, Ant always included its own runtime in the classpath made available to the javac task. So any libraries included with Ant, and any libraries available to ant, are automatically in your build's classpath whether you like it or not. It was decided that this probably wasn't what most people wanted. So now there's an option for it."
Although Gradle has a JavaCompile task, it is impossible to get it to mimic the exact behavior of Ant's javac task for this particular case.  That's not to say that I didn't try as this Gradle forum post can attest to that. But as Luke Daley pointed out to me, you can't have a task's output in the same folder as it's input.  For more information, checkout Chapter 15 of the Gradle manual ("More about Tasks"), specifically Section 9 ("Skiping tasks that are up-to-date")

The only way to get Gradle to do what I want is to use Groovy's AntBuilder class like so:
ant.javac srcdir: '.', includes: 'HelloWorld.java', includeAntRuntime: 'false'
Unfortunately I feel like this is cheating as its not using anything Gradle specific.  Let's look at the Gradle way of compiling a Java file using plugins and conventions.  First we'll apply the Java plugin to our Gradle build script. 
apply plugin: 'java'
Just that one little line of code gives us a bunch of useful tasks that we can run from the command line.
 The one we're interested is the compileJava task which can be executed on the command line like so:
c:\newFolder>gradle compileJava
Before we do that, though, we first need to put the file in a specific folder structure in order for Gradle to find it.  Now I know there are ways to customize this folder structure, but the Gradle convention is to put Java source files in /src/main/java. When we execute the compileJava task, Gradle puts the compiled class file in a /build/classes/main folder.

No comments:

Post a Comment