Search code examples
mavenavro

Using Avro Schemas that refer other Avro Schema to generate specific record class in Java


I have 2 schemas i.e. LogLine and User schemas

{
  "namespace": "com.sample.log",
  "type": "record",
  "name": "User",
  "fields": [
    {"name": "username", "type": "string"},
    {"name": "user_type", "type": "string"},
  ]
}
  
{
  "namespace": "com.sample.log",
  "type": "record",
  "name": "LogLine",
  "fields": [
    {"name": "ip", "type": "string"},
    {"name": "timestamp",  "type": "long"},
    {"name": "url",  "type": "string"},
    {"name": "referrer",  "type": "string"},
    {"name": "useragent",  "type": "string"},
    {"name": "sessionid",  "type": ["null","int"], "default": null}
    {"name": "user",  "type": ["null","user"], "default": null}
  ]
}

I have defined the Logline schema such that I need to refer to another schema "user" schema. I need to generate the specific record class by using the Avro Maven plugin.

When I try to do the same getting error

Failed to execute goal org.apache.avro:avro-maven-plugin:1.8.2:schema (default) on project Logging: Execution default of goal org.apache.avro:avro-maven-plugin:1.8.2:schema failed Undefined Name "User"


Solution

  • Since I was using Avro Maven plugin I need to import the User schema first which is a dependency for Logline schema. Below I have added the import unser the imports section and it worked for me.

             <plugin>
                <groupId>org.apache.avro</groupId>
                <artifactId>avro-maven-plugin</artifactId>
                <version>${avro.version}</version>
                <executions>
                    <execution>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>schema</goal>
                        </goals>
                        <configuration>
                            <sourceDirectory>${project.basedir}/src/main/resources/typedmessages/</sourceDirectory>
                            <imports>
                                <import>${project.basedir}/src/main/resources/typedmessages/user.avsc</import>
                            </imports>
                            <includes>
                                <include>*.avsc</include>
                            </includes>
                            <outputDirectory>${project.build.directory}/generated-sources</outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
    

    More details can be found in the blog: https://feitam.es/use-of-avro-maven-plugin-with-complex-schemas-defined-in-several-files-to-be-reused-in-different-typed-messages/