Search code examples
javaavro

Use of an external java class as a type in an AVRO schema


Is it possible to refer in an avsc file to a Java class already implemented?

My idea is to have something like:

{
    "namespace": "com.myCompany.myProject.schemas",
    "type": "record",
    "name": "SimpleTest",
    "fields": [
      {"name": "text","type": "string"},
      {"name": "myOtherObj","type": "com.myCompany.myProject.MyClass"}
      ]
}

where the field myOtherObj has as type the already defined java class MyClass that is already build.


Solution

  • My solution is: I defined a folder where I define a dummy version of the basic type MyClass, via the MyClass.avsc:

    {
      "namespace": "com.myCompany.myProject.basicTypes",
      "type": "record",
      "name": "MyClass",
      "doc": "This is only a place-holder needed to let Avro compile correctly the schemas. The real implementation is provided in the java project",
      "fields": [
            {"name": "value", "type": "string"}
        ]
    }
    

    then, using the gradle plugin: https://github.com/commercehub-oss/gradle-avro-plugin, I build the avro class SimpleTest together with this. In this way Avro will create SimpleTest.java and MyClass.java and will correctly resolve their dependencies. Finally I remove from the classpath the implementation of MyClass.java created by the Avro plugin.

    //remove the basicTypes as these are only place holder while the real implementation is somewhere else.
    task removeBasicTypes {
        dependsOn compileJava
        doLast {
            println "Removing java files of all the basic types."
            //cleanup the generated java classes
            delete fileTree(dir: 'src/main/java/com/myCompany/myProject/basicTypes' , include: '**/*.java')
            //cleanup also the build folder that will be used to generate the jar file
            delete fileTree(dir: 'build/classes/java/main/com/myCompany/myProject/basicTypes' , include: '**/*.class')
        }
    }
    
    task generateAvro(type: com.commercehub.gradle.plugin.avro.GenerateAvroJavaTask) {
        source("$rootDir/basicTypes", "src/main/avro")
        outputDir = file("src/main/java")
    
        finalizedBy('removeBasicTypes')
    }
    

    The real implementation of this MyClass will be provided as a dependency or in the project where I include this generate SimpleTest.java file.