Skip to content

Instantly share code, notes, and snippets.

@tbroyer
Last active May 25, 2016 13:46
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tbroyer/6847494 to your computer and use it in GitHub Desktop.
Save tbroyer/6847494 to your computer and use it in GitHub Desktop.
Error-prone in Gradle

UPDATE: This is now available as a plugin https://github.com/tbroyer/gradle-errorprone-plugin

To use it, just add the following to your build.gradle and it'll change all JavaCompile tasks to use the error-prone compiler:

apply from: 'https://gist.github.com/tbroyer/6847494/raw/errorprone.gradle'
/*
* Copyright 2013 Thomas Broyer
*
* 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.
*/
logger.warn('You should use the gradle-errorprone-plugin: https://github.com/tbroyer/gradle-errorprone-plugin')
import org.gradle.api.internal.tasks.compile.IncrementalJavaCompiler;
afterEvaluate {
def compileTasks = tasks.withType(JavaCompile)
if (!compileTasks.isEmpty()) {
repositories {
mavenCentral()
}
def errorprone = configurations.detachedConfiguration(dependencies.create('com.google.errorprone:error_prone_core:1.0.3'))
compileTasks.each { task ->
task.javaCompiler = new IncrementalJavaCompiler(new ErrorProneCompilerAdapter(errorprone), null, task.outputs)
}
}
}
import org.gradle.api.internal.tasks.SimpleWorkResult;
import org.gradle.api.internal.tasks.compile.CompilationFailedException;
import org.gradle.api.internal.tasks.compile.JavaCompileSpec;
import org.gradle.api.internal.tasks.compile.JavaCompilerArgumentsBuilder;
import org.gradle.api.tasks.WorkResult;
import org.gradle.internal.jvm.Jvm;
class ErrorProneCompilerAdapter implements org.gradle.api.internal.tasks.compile.Compiler<JavaCompileSpec> {
private static final Logger LOGGER = Logging.getLogger(this)
private Configuration errorprone;
ErrorProneCompilerAdapter(Configuration errorprone) {
this.errorprone = errorprone;
}
public WorkResult execute(JavaCompileSpec spec) {
LOGGER.info("Compiling with Error Prone compiler");
def args = new JavaCompilerArgumentsBuilder(spec).includeSourceFiles(true).build() as String[]
def tccl = Thread.currentThread().contextClassLoader;
def toolsJar = Jvm.current().toolsJar;
def urls = [toolsJar.toURI().toURL()]
errorprone.each { File f ->
urls << f.toURI().toURL()
}
def ccl = new URLClassLoader(urls as URL[], null as ClassLoader);
def javacClass = ccl.loadClass('com.google.errorprone.ErrorProneCompiler$Builder');
def result;
try {
Thread.currentThread().setContextClassLoader(ccl);
def builderInstance = javacClass.newInstance();
def compiler = javacClass.getMethod("build").invoke(builderInstance);
result = compiler.getClass().getMethod("compile", [ String[].class ] as Class[])
.invoke(compiler, [ args ] as Object[]);
} finally {
Thread.currentThread().setContextClassLoader(tccl);
}
if (result != 0) {
throw new CompilationFailedException();
}
return new SimpleWorkResult(true);
}
}
@amrfaissal
Copy link

This is really great! Thanks a lot Thomas.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment