2016-02-24 37 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