diff --git a/hibernate-core/hibernate-core.gradle b/hibernate-core/hibernate-core.gradle
index 73a55c3ba0..9047d5c603 100644
--- a/hibernate-core/hibernate-core.gradle
+++ b/hibernate-core/hibernate-core.gradle
@@ -177,5 +177,5 @@ task jaxb {
}
-runSourceGenerators.dependsOn jaxb
-runSourceGenerators.dependsOn generateGrammarSource
+sourceSets.main.sourceGeneratorsTask.dependsOn jaxb
+sourceSets.main.sourceGeneratorsTask.dependsOn generateGrammarSource
diff --git a/source-generation.gradle b/source-generation.gradle
index 1db18efd79..7585e0dc59 100644
--- a/source-generation.gradle
+++ b/source-generation.gradle
@@ -1,31 +1,19 @@
-import java.nio.charset.Charset
import java.util.concurrent.Callable
-import javax.tools.Diagnostic
-import javax.tools.DiagnosticListener
-import javax.tools.JavaCompiler
-import javax.tools.JavaFileObject
-import javax.tools.StandardJavaFileManager
-import javax.tools.ToolProvider
-
-import org.gradle.api.internal.project.ProjectInternal
-import org.gradle.api.internal.tasks.SimpleWorkResult
-import org.gradle.api.internal.tasks.compile.CompilationFailedException
-import org.gradle.api.internal.tasks.compile.Compiler
-import org.gradle.api.internal.tasks.compile.DefaultJavaCompileSpec
-import org.gradle.api.internal.tasks.compile.DefaultJavaCompilerFactory
-import org.gradle.api.internal.tasks.compile.DelegatingJavaCompiler
-import org.gradle.api.internal.tasks.compile.JavaCompileSpec
-import org.gradle.api.internal.tasks.compile.JavaCompilerArgumentsBuilder
-import org.gradle.api.internal.tasks.compile.JavaCompilerFactory
-import org.gradle.api.internal.tasks.compile.daemon.CompilerDaemonManager
-import org.gradle.api.internal.tasks.compile.jdk6.Jdk6JavaCompiler
-import org.gradle.internal.jvm.Jvm
apply plugin: SourceGenerationPlugin
+/**
+ * A plugin for dealing with AnnotationProcessor-based source generation.
+ *
+ * Creates (or reuses) a grouping task named `generateSources` which is responsible
+ * for coordinating (via task deps) the running of all source-generation tasks.
+ *
+ * Additionally a grouping task is created for each SourceSet to hold the generation
+ * task for that SourceSet. This task is named following the `run{SourceSet.name}SourceGenerators`.
+ * This task is also injected into the SourceSet as `sourceGeneratorsTask` for scripts to access
+ */
class SourceGenerationPlugin implements Plugin {
public static final String GROUP = "sourceGeneration";
-
public static final String GENERATE_SOURCES_TASK_NAME = "generateSources";
@Override
@@ -68,7 +56,20 @@ class SourceGenerationPlugin implements Plugin {
generateSourcesTask.dependsOn( sourceGeneratorsTask );
javaCompileTask.dependsOn( sourceGeneratorsTask );
+ final File aptDir = new File( new File( project.getBuildDir(), "generated-src/apt" ), sourceSet.name );
+ javaCompileTask.options.compilerArgs += [ "-s", aptDir.absolutePath ];
+ javaCompileTask.doFirst({
+ if ( !aptDir.exists() ) {
+ if ( !aptDir.mkdirs() ) {
+ project.logger.warn( "Unable to create APT dir : " + aptDir.absolutePath )
+ }
+ }
+ })
+
+ generateSourcesTask.dependsOn( javaCompileTask )
+
extProps.set( "sourceGeneratorsTask", sourceGeneratorsTask );
+ extProps.set( "aptDir", aptDir );
}
}
}
@@ -80,45 +81,54 @@ class SourceGenerationPluginConvention {
private final Project project;
// practicality says we only ever deal with 2 source-sets:
- private AnnotationProcessorOnlyTask mainProcOnlyTask;
- private AnnotationProcessorOnlyTask testProcOnlyTask;
+ private JavaCompile mainProcOnlyTask;
+ private JavaCompile testProcOnlyTask;
SourceGenerationPluginConvention(Project project) {
this.project = project
}
- private AnnotationProcessorOnlyTask getLocateProcessorOnlyTask(SourceSet sourceSet) {
+ /**
+ * Exposed to the build scripts to be able to apply JPA Metamodel Generation support to the
+ * SourceSet it specifies.
+ *
+ * @param sourceSet The SourceSet to which JPA Metamodel Generation support should be applied.
+ */
+ public void addMetaGenProcessor(SourceSet sourceSet) {
if ( sourceSet.name.equals( "main" ) ) {
if ( mainProcOnlyTask == null ) {
mainProcOnlyTask = generateProcessorOnlyTask( sourceSet )
}
- return mainProcOnlyTask;
}
else if ( sourceSet.name.equals( "test" ) ) {
if ( testProcOnlyTask == null ) {
testProcOnlyTask = generateProcessorOnlyTask( sourceSet )
}
- return testProcOnlyTask;
}
else {
throw new IllegalArgumentException( "SourceSet (" + sourceSet.name + ") not valid for source generation" )
}
}
- private AnnotationProcessorOnlyTask generateProcessorOnlyTask(SourceSet sourceSet) {
+ private JavaCompile generateProcessorOnlyTask(SourceSet sourceSet) {
+ final File targetDir = sourceSet.aptDir;
+
// find the main javac task for this sourceSet (we will alter it a bit later on)
final JavaCompile javaCompileTask = (JavaCompile) project.getTasks().getByName( sourceSet.getCompileJavaTaskName() );
final ExtraPropertiesExtension extProps = ( (ExtensionAware) sourceSet ).getExtensions().getExtraProperties();
- // Obtain the output dir reference: generated-src/apt/{sourceSet.name}
- final File outputDir = new File(
- new File( project.getBuildDir(), "generated-src/apt/" ),
- sourceSet.getName()
- );
-
final String aptTaskName = sourceSet.getTaskName( "run", "annotationProcessors" );
- final AnnotationProcessorOnlyTask aptTask = project.getTasks().create( aptTaskName, AnnotationProcessorOnlyTask.class );
+// final AnnotationProcessorOnlyTask aptTask = project.getTasks().create( aptTaskName, AnnotationProcessorOnlyTask.class );
+ final JavaCompile aptTask = project.getTasks().create( aptTaskName, JavaCompile.class );
+ aptTask.options.compilerArgs += [
+ "-nowarn",
+ "-proc:only",
+ "-encoding", "UTF-8",
+ "-s", targetDir.getAbsolutePath(),
+ "-processor", METAGEN_PROCESSOR_NAME
+ ]
+
aptTask.setGroup( SourceGenerationPlugin.GROUP );
aptTask.setDescription(
String.format(
@@ -132,10 +142,8 @@ class SourceGenerationPluginConvention {
// even as we add to it. The problem is that later on here we will add the output directory of this task
// to this SourceDirectorySet; we need to make sure that we use the view of the SourceDirectorySet *before* that
// happens as the source for this task. getSrcDirs() does that
- aptTask.source( sourceSet.getAllJava().getSrcDirs() )
- aptTask.destinationDir = outputDir
- // again for JBoss Logging...
- aptTask.classesDir = outputDir
+ aptTask.source( sourceSet.getAllJava() )
+ aptTask.destinationDir = targetDir
aptTask.setSourceCompatibility( javaCompileTask.getSourceCompatibility() );
aptTask.setTargetCompatibility( javaCompileTask.getTargetCompatibility() );
@@ -145,7 +153,7 @@ class SourceGenerationPluginConvention {
"classpath",
new Callable() {
public FileCollection call() throws Exception {
- return javaCompileTask.getClasspath()
+ return javaCompileTask.getClasspath() + project.configurations[METAGEN_DEPENDENCY_CONFIG_NAME]
}
}
);
@@ -154,223 +162,10 @@ class SourceGenerationPluginConvention {
javaCompileTask.dependsOn( aptTask );
project.tasks.findByName( SourceGenerationPlugin.GENERATE_SOURCES_TASK_NAME ).dependsOn( aptTask )
-
- // create a FileTree representation of the APT output dir and add it to the JavaCompile task (so they get compiled)
-// final ConfigurableFileTree outputDirFileTree = project.fileTree( outputDir );
-// outputDirFileTree.builtBy( aptTask );
-// javaCompileTask.getSource().plus( outputDirFileTree );
-
// Add the APT output dir to the source set
- sourceSet.getJava().srcDir( outputDir );
+ // - so that the generated sources get compiled during main javac
+ sourceSet.getJava().srcDir( targetDir );
return aptTask
}
-
- public void addMetaGenProcessor(SourceSet sourceSet) {
- AnnotationProcessorOnlyTask task = getLocateProcessorOnlyTask( sourceSet )
- task.processors += METAGEN_PROCESSOR_NAME
- task.classpath += project.configurations[METAGEN_DEPENDENCY_CONFIG_NAME]
- }
}
-class AnnotationProcessorOnlyTask extends AbstractCompile {
- @Input
- def List processors = new ArrayList();
- // todo : support for this? really only "used" for logging and its use is questionable
- //private Map processorSettings = new HashMap();
-
- def File dependencyCacheDir;
- def File classesDir;
-
- private Compiler javaCompiler;
-
- AnnotationProcessorOnlyTask() {
- // Stolen from Gradle's Compile/JavaCompile
- org.gradle.internal.Factory antBuilderFactory = getServices().getFactory( org.gradle.api.AntBuilder.class );
- JavaCompilerFactory inProcessCompilerFactory = new ExpandedJavaCompilerFactory( getLogger() );
- ProjectInternal projectInternal = (ProjectInternal) getProject();
- CompilerDaemonManager compilerDaemonManager = getServices().get( CompilerDaemonManager.class );
- JavaCompilerFactory defaultCompilerFactory = new DefaultJavaCompilerFactory(
- projectInternal,
- antBuilderFactory,
- inProcessCompilerFactory,
- compilerDaemonManager
- );
-
- // The Gradle IncrementalJavaCompiler cant be used here for various reasons
- javaCompiler = new DelegatingJavaCompiler( defaultCompilerFactory );
- }
-
- @OutputDirectory
- public File getDependencyCacheDir() {
- return dependencyCacheDir;
- }
-
- public void setDependencyCacheDir(File dependencyCacheDir) {
- this.dependencyCacheDir = dependencyCacheDir;
- }
-
- @Override
- protected void compile() {
- // see if the output dir exists
- if ( !getDestinationDir().exists() ) {
- // its does not - create it (javac will complain if its not there)
- makeDirectory( getDestinationDir() );
- }
- else {
- // it does - clean it
- project.delete( getDestinationDir() )
- makeDirectory( getDestinationDir() );
- }
-
- if ( !getClassesDir().exists() ) {
- // create classes dir if not there (again, javac will complain if its not there)
- makeDirectory( getClassesDir() );
- }
-
- CompileOptions compileOptions = new CompileOptions();
-
- Collections.addAll(
- compileOptions.getCompilerArgs(),
- "-nowarn",
- "-proc:only",
- "-encoding", "UTF-8",
- "-s", getDestinationDir().getAbsolutePath(),
- "-processor", processors.join( "," )
-
- );
-
- DefaultJavaCompileSpec spec = new DefaultJavaCompileSpec();
- spec.setSource( getSource() );
- // jboss logging needs this :(
- spec.setDestinationDir( getClassesDir() );
- spec.setClasspath( getClasspath() );
- spec.setDependencyCacheDir( dependencyCacheDir );
- spec.setSourceCompatibility( getSourceCompatibility() );
- spec.setTargetCompatibility( getTargetCompatibility() );
- spec.setCompileOptions( compileOptions );
-
- WorkResult result = javaCompiler.execute( spec );
- setDidWork( result.getDidWork() );
- }
-
- @SuppressWarnings("ResultOfMethodCallIgnored")
- private static void makeDirectory(File directory) {
- directory.mkdirs();
- }
-}
-
-/**
- * Implementation of the Gradle JavaCompilerFactory contract generating {@link ExpandedJdk6JavaCompiler} instances
- */
-class ExpandedJavaCompilerFactory implements JavaCompilerFactory {
- private final Logger logger;
-
- public ExpandedJavaCompilerFactory(Logger logger) {
- //To change body of created methods use File | Settings | File Templates.
- this.logger = logger;
- }
-
- @Override
- public Compiler create(CompileOptions options) {
- return new ExpandedJdk6JavaCompiler( logger );
- }
-}
-
-/**
- * Extension of Gradle's Jdk6JavaCompiler to add DiagnosticListener for diagnostic message mapping and APT support
- */
-public class ExpandedJdk6JavaCompiler extends Jdk6JavaCompiler {
- private final Logger logger;
-
- public ExpandedJdk6JavaCompiler(Logger logger) {
- this.logger = logger;
- }
-
- public WorkResult execute(JavaCompileSpec spec) {
- logger.info( "Compiling with JDK Java compiler API." );
-
- final DiagnosticListenerImpl diagnosticListener = new DiagnosticListenerImpl( logger );
- final JavaCompiler.CompilationTask task = createCompileTask( spec, diagnosticListener );
- boolean success = task.call();
- if ( !success || diagnosticListener.sawError() ) {
- throw new CompilationFailedException();
- }
-
- return new SimpleWorkResult( true );
- }
-
- private static JavaCompiler.CompilationTask createCompileTask(
- JavaCompileSpec spec,
- DiagnosticListenerImpl diagnosticListener) {
- List options = new JavaCompilerArgumentsBuilder(spec).build();
- JavaCompiler compiler = findCompiler();
- if ( compiler == null ) {
- throw new RuntimeException("Cannot find System Java Compiler. Ensure that you have installed a JDK (not just a JRE) and configured your JAVA_HOME system variable to point to the according directory.");
- }
- CompileOptions compileOptions = spec.getCompileOptions();
- StandardJavaFileManager fileManager = compiler.getStandardFileManager(
- null,
- null,
- compileOptions.getEncoding() != null
- ? Charset.forName( compileOptions.getEncoding() )
- : null
- );
- Iterable extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(spec.getSource());
- return compiler.getTask(null, null, diagnosticListener, options, null, compilationUnits);
- }
-
-
- private static class DiagnosticListenerImpl implements DiagnosticListener {
- private final Logger logger;
-
- public DiagnosticListenerImpl(Logger logger) {
- this.logger = logger;
- }
-
- @Override
- public void report(Diagnostic extends JavaFileObject> diagnostic) {
- switch ( diagnostic.getKind() ) {
- case Diagnostic.Kind.ERROR:
- logger.debug( "[ERROR] : " + diagnostic.toString() );
- break;
- case Diagnostic.Kind.WARNING:
- logger.debug( "[WARNING] : " + diagnostic.toString() );
- break;
- case Diagnostic.Kind.MANDATORY_WARNING:
- logger.debug( "[MANDATORY_WARNING] : " + diagnostic.toString() );
- break;
- case Diagnostic.Kind.NOTE:
- logger.debug( "[NOTE] : " + diagnostic.toString() );
- break;
- case Diagnostic.Kind.OTHER:
- logger.debug( "[OTHER] : " + diagnostic.toString() );
- break
- default:
- logger.debug( "[UNKNOWN] : " + diagnostic.toString() );
- break;
- }
- }
-
- public boolean sawError() {
- // technically ERROR diagnostics should end the compile cycle, but since we are just generating
- // sources here we ignore errors for now (expecting the later compilation task to report them
- // if still valid)
- return false;
- }
- }
-
- private static JavaCompiler findCompiler() {
- File realJavaHome = Jvm.current().getJavaHome();
- File javaHomeFromToolProvidersPointOfView = new File(System.getProperty("java.home"));
- if (realJavaHome.equals(javaHomeFromToolProvidersPointOfView)) {
- return ToolProvider.getSystemJavaCompiler();
- }
-
- System.setProperty("java.home", realJavaHome.getAbsolutePath());
- try {
- return ToolProvider.getSystemJavaCompiler();
- } finally {
- System.setProperty("java.home", javaHomeFromToolProvidersPointOfView.getAbsolutePath());
- }
- }
-}
diff --git a/tooling/metamodel-generator/hibernate-jpamodelgen.gradle b/tooling/metamodel-generator/hibernate-jpamodelgen.gradle
index 5b8258a162..caaed83397 100644
--- a/tooling/metamodel-generator/hibernate-jpamodelgen.gradle
+++ b/tooling/metamodel-generator/hibernate-jpamodelgen.gradle
@@ -64,7 +64,8 @@ task jaxb {
}
}
}
-runSourceGenerators.dependsOn jaxb
+
+sourceSets.main.sourceGeneratorsTask.dependsOn jaxb
checkstyleMain.exclude '**/jaxb/**'