2016-02-24 36 views
0

我正在编写一个工具,使用Avro 1.8.0将数据从本地格式转换为Avro,JSON和Parquet。转换的Avro和实木复合地板的工作不错,但JSON的转换引发以下错误:Avro Json.ObjectWriter - “不是Json架构”错误

Exception in thread "main" java.lang.RuntimeException: Not the Json schema: 
{"type":"record","name":"Torperf","namespace":"converTor.torperf", 
"fields":[{"name":"descriptor_type","type":"string"," 
[... rest of the schema omitted for brevity] 

不快。这是我沿着过去了,这的确想转换器使用的模式。我不知道Avro在抱怨什么。 这是我的代码的相关片段:

// parse the schema file 
Schema.Parser parser = new Schema.Parser(); 
Schema mySchema; 
// tried two ways to load the schema 
// like this 
File schemaFile = new File("myJsonSchema.avsc"); 
mySchema = parser.parse(schemaFile) ; 
// and also like Json.class loads it's schema 
mySchema = parser.parse(Json.class.getResourceAsStream("myJsonSchema.avsc")); 

// initialize the writer 
Json.ObjectWriter jsonDatumWriter = new Json.ObjectWriter(); 
jsonDatumWriter.setSchema(mySchema); 
OutputStream out = new FileOutputStream(new File("output.avro")); 
Encoder encoder = EncoderFactory.get().jsonEncoder(mySchema, out); 

// append a record created by way of a specific mapping 
jsonDatumWriter.write(specificRecord, encoder); 

我取代myJsonSchema.avsc与一个从异常返回没有成功(和除空格和换行,他们是相同的)。用org.apache.avro.data.Json.SCHEMA而不是mySchema初始化jsonEncoder也没有改变任何东西。用org.apache.avro.data.Json.SCHEMA替换传递给Json.ObjectWriter的模式会导致org.apache.avro.data.Json.write(Json.java:183)(这是一个废弃的方法)的NullPointerException。

从凝视着org.apache.avro.data.Json.java,我觉得像Avro正在检查我自己的记录模式,以对照它自己的Json记录(第58行)的模式进行相等(第73行)。

58 SCHEMA = Schema.parse(Json.class.getResourceAsStream("/org/apache/avro/data/Json.avsc")); 

72 public void setSchema(Schema schema) { 
73 if(!Json.SCHEMA.equals(schema)) 
74  throw new RuntimeException("Not the Json schema: " + schema); 
75 } 

引用的Json.avsc定义字段类型的记录的:

{"type": "record", "name": "Json", "namespace":"org.apache.avro.data", 
"fields": [ 
    {"name": "value", 
     "type": [ 
      "long", 
      "double", 
      "string", 
      "boolean", 
      "null", 
      {"type": "array", "items": "Json"}, 
      {"type": "map", "values": "Json"} 
     ] 
    } 
] 
} 

equals在org.apache.avro.Schema实现的,线346:

public boolean equals(Object o) { 
    if(o == this) { 
     return true; 
    } else if(!(o instanceof Schema)) { 
     return false; 
    } else { 
     Schema that = (Schema)o; 
     return this.type != that.type?false:this.equalCachedHash(that) && this.props.equals(that.props); 
    } 
    } 

我不完全理解第三次检查(尤其是equalCachedHash())中发生了什么,但我只能以平凡的方式识别检查是否相等,这对我来说没有任何意义。

另外我找不到有关在InterWebs上使用Avro的Json.ObjectWriter的示例或注释。我想知道是否应该使用已弃用的Json.Writer,因为至少有几个代码片段可供在线学习和收集。

完整的源代码可在https://github.com/tomlurge/converTor

感谢,
托马斯

回答

0

多一点的调试论证了传递org.apache.avro.data.Json.SCHEMA到Json.ObjectWriter确实是做正确的事。我返回写入System.out的对象打印我期望的JSON对象。空指针异常虽然没有消失。 也许我不会必须setSchema()的Json.ObjectWriter在所有,因为省略了alltogether命令导致相同的NullPointerException。

我终于提交了一个与Avro的错误,事实证明,在我的代码中,我将一个“特定”类型的对象交给ObjectWriter,它无法处理。它虽然默默回归,只是在稍后阶段才抛出错误。这在Avro 1.8.1中得到了修复 - 详情请参阅https://issues.apache.org/jira/browse/AVRO-1807