You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Maven构建中将.avsc Avro Schema文件转换为.avdl文件?

在Maven构建流程中实现Avsc到Avdl格式的转换方案

针对你提到的现有插件限制,我们可以借助Avro的原生Java API,结合Maven的通用执行类插件或脚本插件来实现转换,以下是两种可行方案:

方案一:使用Groovy Maven插件编写转换脚本

Groovy脚本可以直接调用Avro API,无需额外编译Java类,适合快速实现转换逻辑。

1. 在pom.xml中配置Groovy Maven插件

<build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.gmavenplus</groupId>
            <artifactId>gmavenplus-plugin</artifactId>
            <version>1.13.1</version>
            <executions>
                <execution>
                    <id>convert-avsc-to-avdl</id>
                    <phase>generate-sources</phase>
                    <goals>
                        <goal>execute</goal>
                    </goals>
                    <configuration>
                        <scripts>
                            <script>${project.basedir}/src/main/groovy/AvscToAvdlConverter.groovy</script>
                        </scripts>
                        <properties>
                            <inputDir>${project.basedir}/src/main/resources/avsc</inputDir>
                            <outputDir>${project.basedir}/target/generated-resources/avdl</outputDir>
                        </properties>
                    </configuration>
                </execution>
            </executions>
            <dependencies>
                <dependency>
                    <groupId>org.apache.avro</groupId>
                    <artifactId>avro</artifactId>
                    <version>1.11.3</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>

2. 编写Groovy转换脚本 AvscToAvdlConverter.groovy

import org.apache.avro.Schema
import org.apache.avro.Schema.Type

def inputDir = new File(properties.inputDir)
def outputDir = new File(properties.outputDir)
outputDir.mkdirs()

inputDir.eachFileMatch(~/.*\.avsc/) { file ->
    def schema = new Schema.Parser().parse(file)
    def avdlContent = generateAvdl(schema)
    
    def outputFile = new File(outputDir, "${schema.getName()}.avdl")
    outputFile.write(avdlContent, "UTF-8")
    println "Converted ${file.name} to ${outputFile.name}"
}

String generateAvdl(Schema schema) {
    def sb = new StringBuilder()
    // 写入命名空间
    if (schema.getNamespace()) {
        sb.append("namespace ${schema.getNamespace()};\n\n")
    }
    // 写入类型定义
    sb.append("protocol ${schema.getName()}Protocol {\n")
    sb.append("    ${generateTypeDefinition(schema)}\n")
    sb.append("}\n")
    return sb.toString()
}

String generateTypeDefinition(Schema schema) {
    switch (schema.getType()) {
        case Type.RECORD:
            def fields = schema.getFields().collect { field ->
                "    ${field.name()}: ${getTypeString(field.schema())};"
            }.join("\n")
            return "record ${schema.getName()} {\n${fields}\n  }"
        case Type.ENUM:
            def symbols = schema.getEnumSymbols().join(", ")
            return "enum ${schema.getName()} {\n    ${symbols}\n  }"
        case Type.UNION:
            return schema.getTypes().collect { getTypeString(it) }.join(" | ")
        default:
            return schema.getType().name().toLowerCase()
    }
}

String getTypeString(Schema schema) {
    if (schema.getType().name() in ['RECORD', 'ENUM']) {
        return schema.getFullName()
    } else if (schema.getType() == Type.ARRAY) {
        return "array<${getTypeString(schema.getElementType())}>"
    } else if (schema.getType() == Type.MAP) {
        return "map<${getTypeString(schema.getValueType())}>"
    } else if (schema.getType() == Type.UNION) {
        return schema.getTypes().collect { getTypeString(it) }.join(" | ")
    } else {
        return schema.getType().name().toLowerCase()
    }
}

这个脚本会遍历指定目录下的所有.avsc文件,解析后生成对应的Avdl协议文件,包含基本的记录、枚举、联合类型等转换逻辑,可根据你的schema复杂度扩展。

方案二:自定义Java工具类 + Maven Exec插件

如果更习惯Java开发,可以编写一个工具类实现转换,再用Exec插件调用。

1. 编写Java转换工具类

import org.apache.avro.Schema;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class AvscToAvdlConverter {
    public static void main(String[] args) throws IOException {
        String inputDirPath = args[0];
        String outputDirPath = args[1];
        
        File inputDir = new File(inputDirPath);
        File outputDir = new File(outputDirPath);
        if (!outputDir.exists()) {
            outputDir.mkdirs();
        }
        
        for (File file : inputDir.listFiles((dir, name) -> name.endsWith(".avsc"))) {
            Schema schema = new Schema.Parser().parse(file);
            String avdlContent = generateAvdl(schema);
            
            File outputFile = new File(outputDir, schema.getName() + ".avdl");
            try (FileWriter writer = new FileWriter(outputFile)) {
                writer.write(avdlContent);
            }
            System.out.println("Converted " + file.getName() + " to " + outputFile.getName());
        }
    }
    
    private static String generateAvdl(Schema schema) {
        StringBuilder sb = new StringBuilder();
        if (schema.getNamespace() != null) {
            sb.append("namespace ").append(schema.getNamespace()).append(";\n\n");
        }
        sb.append("protocol ").append(schema.getName()).append("Protocol {\n");
        sb.append("    ").append(generateTypeDefinition(schema)).append("\n");
        sb.append("}\n");
        return sb.toString();
    }
    
    private static String generateTypeDefinition(Schema schema) {
        switch (schema.getType()) {
            case RECORD:
                StringBuilder fieldsSb = new StringBuilder();
                for (Schema.Field field : schema.getFields()) {
                    fieldsSb.append("    ").append(field.name()).append(": ")
                            .append(getTypeString(field.schema())).append(";\n");
                }
                return "record " + schema.getName() + " {\n" + fieldsSb + "  }";
            case ENUM:
                String symbols = String.join(", ", schema.getEnumSymbols());
                return "enum " + schema.getName() + " {\n    " + symbols + "\n  }";
            case UNION:
                return String.join(" | ", schema.getTypes().stream().map(AvscToAvdlConverter::getTypeString).toList());
            default:
                return schema.getType().name().toLowerCase();
        }
    }
    
    private static String getTypeString(Schema schema) {
        return switch (schema.getType()) {
            case RECORD, ENUM -> schema.getFullName();
            case ARRAY -> "array<" + getTypeString(schema.getElementType()) + ">";
            case MAP -> "map<" + getTypeString(schema.getValueType()) + ">";
            case UNION -> String.join(" | ", schema.getTypes().stream().map(AvscToAvdlConverter::getTypeString).toList());
            default -> schema.getType().name().toLowerCase();
        };
    }
}

2. 在pom.xml中配置Exec插件

<build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>convert-avsc-to-avdl</id>
                    <phase>generate-sources</phase>
                    <goals>
                        <goal>java</goal>
                    </goals>
                    <configuration>
                        <mainClass>com.yourpackage.AvscToAvdlConverter</mainClass>
                        <arguments>
                            <argument>${project.basedir}/src/main/resources/avsc</argument>
                            <argument>${project.basedir}/target/generated-resources/avdl</argument>
                        </arguments>
                    </configuration>
                </execution>
            </executions>
            <dependencies>
                <dependency>
                    <groupId>org.apache.avro</groupId>
                    <artifactId>avro</artifactId>
                    <version>1.11.3</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>

注意事项

  • 确保Avro依赖版本与你的项目一致,避免兼容性问题
  • 上述代码支持基本的Avro类型转换,若你的schema包含复杂嵌套、自定义逻辑,可扩展generateTypeDefinition方法
  • 转换后的Avdl文件会输出到target/generated-resources/avdl目录,可根据需求调整路径

内容的提问来源于stack exchange,提问作者Harold L. Brown

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 21:15:07