javagradlecode-generationavroavro-tools

How to generate Java classes from Avro schemas as part of a Gradle build?


For Maven there is an official Avro plugin to generate Java classes from Avro schemas.

However, for Gradle there exists no official plugin.

There is davidmc24/gradle-avro-plugin, but it is no longer maintained and it is looking for a maintainer.

How can I generate Java classes from Avro schemas as part of a Gradle build?


Solution

  • I have now created a simple Gradle task that generates the Avro Java classes.

    import org.apache.avro.tool.SpecificCompilerTool
    
    buildscript {
        dependencies {
            // Add the Avro code generation to the build dependencies so that it can be used in a Gradle task.
            classpath group: 'org.apache.avro', name: 'avro-tools', version: '1.11.1'
        }
    }
    
    plugins {
        // some project plugins
        id 'application'
    }
    
    def avroSchemasDir = "src/main/avro"
    def avroCodeGenerationDir = "build/generated-main-avro-java"
    
    // Add the generated Avro Java code to the Gradle source files.
    sourceSets.main.java.srcDirs += [avroCodeGenerationDir]
    
    dependencies {
        // some project dependencies
    }
    
    tasks.register('avroCodeGeneration') {
        // Define the task inputs and outputs for the Gradle up-to-date checks.
        inputs.dir(avroSchemasDir)
        outputs.dir(avroCodeGenerationDir)
        // The Avro code generation logs to the standard streams. Redirect the standard streams to the Gradle log.
        logging.captureStandardOutput(LogLevel.INFO);
        logging.captureStandardError(LogLevel.ERROR)
        doLast {
            // Run the Avro code generation.
            new SpecificCompilerTool().run(System.in, System.out, System.err, List.of(
                    "-encoding", "UTF-8",
                    "-string",
                    "-fieldVisibility", "private",
                    "-noSetters",
                    "schema", "$projectDir/$avroSchemasDir".toString(), "$projectDir/$avroCodeGenerationDir".toString()
            ))
        }
    }
    
    tasks.withType(JavaCompile).configureEach {
        // Make Java compilation tasks depend on the Avro code generation task.
        dependsOn('avroCodeGeneration')
    }
    

    This task can be added to any Gradle build script.