Content tagged: ant

Fail your Build on Java Compiler Warnings


Sat Sep 12 16:37:41 2015 -0700

I hate seeing compiler warnings in code, and anyone who argues that ignoring them is a fine software engineering policy, should be swiftly relieved of their position. Warnings call out mistakes, and occasional blatant stupidity that should not be ignored — heck just Google “pay attention to compiler warnings” for some fun anecdotes. Folks in software are generally helpful, and compiler writers don’t inject annoying warnings because they are mean-spirited. Instead, people want to help, and consequently, compiler warnings are there to help. I’ve personally worked on several stacks with literally thousands of compiler warnings peppered throughout the code — it’s miraculous that some of those applications worked at all.

To combat warning hell, I’ve made it a personal best practice to do two things:

  1. In mature code bases, never introduce more warnings and never ignore existing warnings I happen to stumble across. Ever. If I see a warning in an area of code that I’m working on, I’ll clean it up — no excuses.
  2. In new projects, starting from scratch, set my build tool to immediately fail the build on any warning. In other words, treat warnings as compilation errors!

The latter is surprisingly easy and very effective at forcibly setting a high bar before entropy can gain a foothold.

Here’s how, with a few popular build tools:


If you’re still using Ant, set a series of <compilerarg> tags in your <javac> tasks. Of course, this goes in your build.xml:

<javac srcdir="${src.dir}" destdir="${classes.dir}" classpathref="libraries">
  <compilerarg value="-Xlint:all"/>
  <compilerarg value="-Xlint:-processing"/>
  <compilerarg value="-Xlint:-serial"/>
  <compilerarg value="-Werror"/>


Using the maven-compiler-plugin add a few <compilerArgs> to your configuration within your pom.xml:



To fail the build on any compiler warning, in main source and in test source, set this in your build.gradle:

tasks.withType(JavaCompile) {
  options.compilerArgs << "-Xlint:all" << "-Xlint:-processing" << "-Xlint:-serial" << "-Werror"


In the unlikely event that you’re building a pure Java project or Java source with SBT, set this in your project/Build.scala:

lazy val projectSettings = Defaults.coreDefaultSettings ++ Seq(
  scalacOptions ++= Seq(
    "-deprecation", "-unchecked", "-feature", "-Xlint", "-Xfatal-warnings", "-encoding", "utf8"
  javacOptions ++= Seq(
    "-Xlint:all,-processing,-serial", "-Werror", "-encoding", "utf8", "-g"

The Scala compiler scalac equivalent to -Werror is -Xfatal-warnings (apparently).

A few notes

The magic is in -Werror which is documented here. When set, -Werror terminates compilation when warnings are found.

I’m also passing -Xlint:-processing which disables any annotation processor warnings from JARs on the compile classpath. And lastly, -Xlint:-serial disables any warnings complaining of Serializable classes that do not have an explicit serialVersionUID field. Ok, yes, certainly one could argue that ignoring complaints about a missing serialVersionUID field is dangerous, but I’ll let you be the judge.


Integrating Ant and Google's Closure Compiler


Sat Aug 21 12:45:00 2010 -0700

With a little spare time on my hands, I dug into Google’s Closure Compiler, an open-source tool that minifies and optimizes JavaScript for better performance. Unlike other JavaScript compression tools like JSMin, Packer or the YUI compressor, Google’s Closure Compiler converts your decent JavaScript into “better” JavaScript. It does so by searching for and pointing out obvious JavaScript pitfalls, deleting dead code, and optimizing what’s left to make your web-applications more efficient. This all sounds great, so I gave it a whirl and eventually integrated it into my Ant build for a new project. Heck, I even found a bug and suggested an enhancement.

$jQuery Users be Warned

Before you run off and have a field day with the Closure Compiler, you should know that optimizing jQuery with the compiler’s ADVANCED_OPTIMIZATIONS mode failed miserably. Even with a proper JS externs file, I could not get jQuery, or my JavaScript that uses jQuery, to compile under ADVANCED_OPTIMIZATIONS mode. Ok, actually it compiled fine, but when I tried to run this JavaScript in a browser: welcome to JavaScript Error City, population one.

Eventually, I gave up and reverted back to SIMPLE_OPTIMIZATIONS mode instead. This works much better. If you know something I don’t about compiling jQuery in advanced mode, please let me know.

Get ’er done

First things first, you’ll need to download the Closure Compiler JAR and integrate it into your Ant build file by defining a new Ant task:

<property name="jscompjar"
  location="${lib.dir}/google-closure-compiler.jar" />

<taskdef name="jscomp"

Yay, now you have a <jscomp> Ant task.


Next, you’ll need Ant to concatenate each of your JavaScript files into a single file. Technically, you don’t have to do this, but I found it much easier and I like having all of my JavaScript compressed into a single resource:

<concat destfile="${build.dir}/js/project.js">
  <filelist dir="${source.js.dir}">
    <file name="underscore-1.0.4.min.js" />
    <file name="jquery-1.4.2.min.js" />
    <file name="jquery-ui-1.8.4.min.js" />
    <file name="project.util.js" />
    <file name="project.js" />

Note that I’m using a FileList instead of a FileSet. This is because the order in which the resources are concatenated is important; they should be concatenated in the order in which they are required, and using a FileList ensures proper order.

Also, note that if you eventually plan on compiling your JavaScript with ADVANCED_OPTIMIZATIONS enabled, you’ll need to concatenate your JavaScript files together anyways. Further, using a single JavaScript resource across your entire site has obvious performance advantages. HTTP operations are usually expensive (especially on mobile devices), so having a web-browser download one large JavaScript file with everything in it is usually better than having it download multiple smaller files. Of course, you could even take it a step further and use a tool like LABjs to load your JavaScript dynamically, as needed.


Ok, now that your JavaScript files have been concatenated into a single resource, let’s use the <jscomp> Ant task we defined earlier to compile it:

<jscomp compilationLevel="simple" warning="quiet"
  debug="false" output="${release.js.dir}/project.min.js">
  <sources dir="${build.dir}/js">
    <file name="project.js" />

Assuming your code compiled cleanly, you’ll have a Closure Compiler optimized JavaScript file sitting around ready for deployment!