使用外部 java class 作为 AVRO 模式中的类型

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

是否可以在 avsc 文件中引用已经实现的 Java class?

我的想法是:

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

其中字段 myOtherObj 具有已定义的类型 java class MyClass 已经构建。

我的解决办法是: 我定义了一个文件夹,我通过 MyClass.avsc:

定义了基本类型 MyClass 的虚拟版本
{
  "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"}
    ]
}

然后,使用 gradle 插件:https://github.com/commercehub-oss/gradle-avro-plugin,我一起构建了 avro class SimpleTest。 通过这种方式,Avro 将创建 SimpleTest.javaMyClass.java 并将正确解析它们的依赖关系。 最后,我从 class 路径中删除了由 Avro 插件创建的 MyClass.java 的实现。

//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')
}

这个 MyClass 的真正实现将作为依赖项或在我包含这个生成 SimpleTest.java 文件的项目中提供。