How to use eclipse JDT compiler with gradle 1.0-milestone-9?

How can I use Eclipse JDT compiler in 1.0-m9? Before gradle-1.0-m8a, it works this way:

compileJava {
        options.compiler = "org.eclipse.jdt.core.JDTCompilerAdapter"
        options.encoding = 'utf-8'
        options.define(compilerArgs: ["-warn:+${warnings.join(',')}"])
        doFirst {
            ClassLoader antClassLoader = org.apache.tools.ant.Project.class.classLoader
            configurations.ecj.each { File f ->
                antClassLoader.addURL(f.toURI().toURL())
            }
        }
    }

But ‘options.compiler’ property is deprecated in 1.0-m8a, so I try the ‘useAnt’ options, like this:

tasks.withType(Compile) {
        ant.properties['build.compiler'] = 'org.eclipse.jdt.core.JDTCompilerAdapter'
        options.useAnt = true
        options.encoding = 'utf-8'
        options.define compilerArgs: [ ... ]
          doFirst {
            ClassLoader antClassLoader = org.apache.tools.ant.Project.class.classLoader
            configurations.ecj.each { File f ->
                antClassLoader.addURL(f.toURI().toURL())
            }
        }
    }

But I got compiler errors, it seems ant always using ‘javac’. After digging into gradle’s source, I found ‘AntJavaCompiler.execute’ uses a new instance of AntBuilder for every compilation. So I have no chance to specify an alternative compiler, without touching the deprecated ‘options.compiler’ property.

So, is there a way to use an alternative compiler, through an Ant CompilerAdapter (such as JDTCompilerAdapter)?

If you need to use an Ant CompilerAdapter, ‘options.compiler’ together with ‘options.useAnt = true’ is the only way. Aren’t there any other ways to use the Eclipse JDT compiler, for example as a standalone Java application?

Instead of ‘options.define compilerArgs: […]’, ‘options.compilerArgs = …’ should be used.

Yes, ecj can be used in command line. In fact, I’m using it this way:

compileJava {
    options.fork = true
    options.define compilerArgs: [
        '-encoding', 'utf-8',
        '-source', sourceCompatibility,
        '-target', targetCompatibility,
        ...
    ]
      doFirst {
        options.fork executable: 'java', jvmArgs: [ '-cp', configurations.ecj.asPath, 'org.eclipse.jdt.internal.compiler.batch.Main' ]
    }
}

But, the compiler executable is ‘java’, I think it’s not the best way to do this.

It will be a good news to me, if Gradle supports Ant’s ‘compiler’ or ‘build.compiler’ property, in the future versions (maybe?)

This can be simplified to:

compileJava {
  options.encoding = 'utf-8'
  options.fork = true
  doFirst {
    options.forkOptions.with {
      executable = 'java'
      jvmArgs = [ '-cp', configurations.ecj.asPath, 'org.eclipse.jdt.internal.compiler.batch.Main' ]
    }
  }
}

We could think about making it easier to execute Java compilers from a main method, or add special support for the Eclipse compiler. Ant’s ‘options.compiler’ is unlikely to come back because Gradle’s ‘Compile’ task is slowly but surely moving away from Ant. Of course, you’ll always be able to use an Ant task (like javac) directly.

Got it, thanks a lot!

GRADLE-3085 (when implemented) should also make it possible to use ECJ through ‘javax.tools.JavaCompiler’ API.