使用Kite-data-core转换JSON到Avro Schema失败,求解决方案
问题描述
尝试使用Kite SDK的JsonUtil工具将JSON字符串转换为Avro Schema,代码如下:
String json = "{\n" + " \"id\": 1,\n" + " \"name\": \"A green door\",\n" + " \"price\": 12.50,\n" + " \"tags\": [\"home\", \"green\"]\n" + "}\n"; Schema avroSchema = JsonUtil.inferSchema(JsonUtil.parse(json), "myschema"); System.out.println(avroSchema.toString());
运行时抛出错误:
Exception in thread "main" java.lang.NoSuchMethodError: 'void org.apache.avro.Schema$Field.<init>(java.lang.String, org.apache.avro.Schema, java.lang.String, org.codehaus.jackson.JsonNode)' at org.kitesdk.data.spi.JsonUtil$JsonSchemaVisitor.object(JsonUtil.java:569) at org.kitesdk.data.spi.JsonUtil$JsonSchemaVisitor.object(JsonUtil.java:547) at org.kitesdk.data.spi.JsonUtil.visit(JsonUtil.java:181) at org.kitesdk.data.spi.JsonUtil.visit(JsonUtil.java:177) at org.kitesdk.data.spi.JsonUtil.inferSchema(JsonUtil.java:540)
解决方案
这个错误是Avro版本与Kite SDK不兼容导致的:
- Kite SDK旧版本依赖Avro 1.7.x系列,该版本的
Schema.Field构造函数包含JsonNode参数; - 若项目引入了Avro 1.8+版本,该构造函数已被移除,因此出现
NoSuchMethodError。
解决方式分三种:
1. 统一Avro依赖版本
查看你使用的Kite SDK版本对应的Avro依赖版本(可在Kite的pom.xml中找到),然后在项目的依赖管理中强制引入该版本的Avro,避免依赖冲突。
比如,若Kite依赖Avro 1.7.7,在Maven中添加:
<dependencyManagement> <dependencies> <dependency> <groupId>org.apache.avro</groupId> <artifactId>avro</artifactId> <version>1.7.7</version> </dependency> </dependencies> </dependencyManagement>
2. 改用Avro官方的Schema推断工具
如果无法调整Avro版本,直接使用Avro官方提供的SchemaInferer来推断Schema,示例代码:
import org.apache.avro.Schema; import org.apache.avro.SchemaInferer; import java.io.ByteArrayInputStream; import java.io.InputStream; public class AvroSchemaInfer { public static void main(String[] args) throws Exception { String json = "{\n" + " \"id\": 1,\n" + " \"name\": \"A green door\",\n" + " \"price\": 12.50,\n" + " \"tags\": [\"home\", \"green\"]\n" + "}\n"; InputStream inputStream = new ByteArrayInputStream(json.getBytes()); Schema schema = SchemaInferer.inferSchema(inputStream, SchemaInferer.SCHEMA_INFERENCE_CONFIG_DEFAULT); System.out.println(schema.toString(true)); } }
3. 手动构建Avro Schema
如果JSON结构固定,也可以手动编写Schema定义,避免版本兼容问题:
import org.apache.avro.Schema; import org.apache.avro.SchemaBuilder; public class ManualAvroSchema { public static void main(String[] args) { Schema schema = SchemaBuilder.record("myschema") .fields() .name("id").type().intType().noDefault() .name("name").type().stringType().noDefault() .name("price").type().doubleType().noDefault() .name("tags").type().array().items().stringType().noDefault() .endRecord(); System.out.println(schema.toString(true)); } }
内容的提问来源于stack exchange,提问作者lostInJava
相关产品推荐
相关产品推荐

