Gradle Plugin that generates .java and .class files

I’m creating a plugin that uses some existing code generation library to provide some classes to the project that uses the plugin. The output of that library is both some plain Java source plus some generated .class files (for some bits, that library outputs only bytecode, no source code).

I put the output of the library into build/generatedSource and build/generatedClasses. Now I need to tell Gradle that A) files in build/generatedSource need to be compiled and B) the files in build/generatedClasses need to be put onto the classpath and included in the assembled JAR.

I manage to do A) like this:

SourceSet sourceSets = project.getConvention()
            .getPlugin(JavaPluginConvention.class).getSourceSets()
            .findByName("main");
Path source = project.getBuildDir().toPath().resolve("generatedSource")
sourceSets.java(sourceSet -> {
            sourceSet.srcDir(source.toFile());
});

But I cannot figure out how to get B) right. I can tell the library to put the generated .class files into build/classes/java/main, but it feels like a hack to me. Putting them into build/classes/something/main would make sense to me, but how do I then tell Gradle to treat that directory similar to build/classes/java/main?

Also, ideally, the Eclipse plugin would understand that there is another directory with already compiled .class files that it needs to include in the buildpath

I’ll write it in groovy because I’m too lazy to do it in java.
Pls adapt as necessary

apply plugin: 'java'
dependencies {
   // add classes dir to compile classpath
   compile files("$buildDir/generated/classes")
}
sourceSets.main.java.srcDir "$buildDir/generated/java" // notice I'm calling "srcDir" not "setSrcDir"
task generate {
   outputs.dir "$buildDir/generated"
   doLast {
      // generate files in $buildDir/generated/java and $buildDir/generated/classes
   }
}
compileJava.dependsOn "generate"
processResources {
   dependsOn "generate" 
   from "$buildDir/generated/classes" // add generated classes to the jar
}
1 Like

Thanks a lot, that does the trick.

It usually takes me ages to translate even tiny bits of Groovy code to Java, just don’t know where to look it up and googling usually gives many many false positives. So for any future visitors of this thread, just for the sake of completeness, how it can be done in Java:

Add generated sources to source sets:

SourceSet sourceSets = project.getConvention()
        .getPlugin(JavaPluginConvention.class).getSourceSets()
        .findByName("main");
sourceSets.java(sourceSet -> {
    sourceSet.srcDir(source);
});

Add generated .class directory as dependency:

ConfigurableFileCollection files = project.files(classes);
DependencyHandler dependencies = project.getDependencies();
dependencies.add("compile", dependencies.create(files));

Add dependencies on our generation task:

project.getTasks().findByName("compileJava").dependsOn(task);
project.getTasks().findByName("processResources").dependsOn(task);

Configure processing of resources:

ProcessResources processResources = (ProcessResources) project.getTasks()
        .findByName("processResources");
processResources.from(classes);