Clojure 使用Avro会抛出格式不正确的数据的AvroRuntimeException

Clojure 使用Avro会抛出格式不正确的数据的AvroRuntimeException,clojure,avro,Clojure,Avro,我有以下代码: (defn parse-schema "Returns an Avro schema" ^Schema$RecordSchema [^String schema-file] (let [schema (File. schema-file)] (.parse (Schema$Parser.) schema-file))) (defn get-reader "Returns a DatumReader" ^SpecificDatumReader [^Sc

我有以下代码:

(defn parse-schema
  "Returns an Avro schema"
  ^Schema$RecordSchema [^String schema-file]
  (let [schema (File. schema-file)]
    (.parse (Schema$Parser.) schema-file)))

(defn get-reader
  "Returns a DatumReader"
  ^SpecificDatumReader [^Schema$RecordSchema schema]
  (SpecificDatumReader. schema))

(defn byte-to-object
  "Returns an object from a byte[]"
  [reader message]
  (let [ decoder (.binaryDecoder (DecoderFactory/get) message nil) ]
    (.read reader nil decoder)))
使用repl中的代码:

plugflow.main=> (avro/parse-schema "schema/test.avsc")
#object[org.apache.avro.Schema$RecordSchema 0x6e896dd7 "{\"type\":\"record\",\"name\":\"test\",\"namespace\":\"com.streambright.avro\",\"fields\":[{\"name\":\"user_name\",\"type\":\"string\",\"doc\":\"User name of any user\"}],\"doc:\":\"Nothing to see here...\"}"]
plugflow.main=> (def record-schema (avro/parse-schema "schema/test.avsc"))
#'plugflow.main/record-schema
plugflow.main=> (avro/get-reader record-schema)
#object[org.apache.avro.specific.SpecificDatumReader 0x56b1cac6 "org.apache.avro.specific.SpecificDatumReader@56b1cac6"]
plugflow.main=> (def avro-reader (avro/get-reader record-schema))
#'plugflow.main/avro-reader
plugflow.main=> (import '[java.nio.file Files Paths Path])
java.nio.file.Path
plugflow.main=> (import '[java.net URI])
java.net.URI
plugflow.main=> (def byte-arr (Files/readAllBytes (Paths/get (URI. "file:///data/test.avro"))))
#'plugflow.main/byte-arr
plugflow.main=> (avro/byte-to-object avro-reader byte-arr))
AvroRuntimeException Malformed data. Length is negative: -40  org.apache.avro.io.BinaryDecoder.doReadBytes (BinaryDecoder.java:336)
使用Avro CLI:

java -jar avro-tools-1.8.1.jar tojson data/test.avro
log4j:WARN No appenders could be found for logger (org.apache.hadoop.metrics2.lib.MutableMetricsFactory).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
{"user_name":"tibi"}

我缺少什么?

事实证明有两组Avro类,一个用于读取和写入Avro文件,另一个用于读取和写入Avro编码的消息。在使用avro cli的情况下,它会写入包含架构的正确avro文件。当我试图用设计用于处理Avro编码消息的函数读取文件时,它显然失败了

在没有模式的情况下编写单个Avro消息的正确方法(如果您希望在单元测试或集成测试中使用它)

Schema Schema=new Schema.Parser().parse(“{\n\”type\”:“record\”,\n\“name\”:“User\”,\n\“namespace\”:“com.streambright\”,\n\”fields\“:[{\n\”name\”:“User\u name\”,\n\“type\”:“string\”,\n\“doc\”:“username\”:“username\”,{\n\”:“username\”:“age\”,\n\”doc\“\n},{\n\'name\':\'weight\',\n\'type\':\'float\',\n\'doc\':\'weight of the user\'”\n},{\n\'name\':\'address\',\n\'type\':{\n\'type\':\'record\',\n\'name\':\'address\',\n\'fields\':[{\n\'name\'name\':'street\'address\',\n\'type\'string\'n\'name\',\n\“type\”:\“string\”\n}]\n}\n}],\n\“doc:\”:\“此处无内容…”“\n}”);
用户=新用户();
user.setUserName(“Tibi Kovacs”);
用户设置(25);
用户设定重量(((浮动)32.12));
user.setAddress(新地址(“FoxiMaxi St”、“布达佩斯”);
SpecificDatumWriter avroEventWriter=新SpecificDatumWriter(模式);
EncoderFactory avroEncoderFactory=EncoderFactory.get();
ByteArrayOutputStream=新建ByteArrayOutputStream();
BinaryEncoder BinaryEncoder=avroEncoderFactory.BinaryEncoder(流,空);
写入(用户,二进制编码器);
binaryEncoder.flush();
IOUtils.安静地关闭(流);
字节[]m=stream.toByteArray();
FileOutputStream fos=newfileoutputstream(“/full/path/data/test3.java.avro”);
fos.write(m);
fos.close();
    Schema schema = new Schema.Parser().parse("{\n  \"type\": \"record\",\n  \"name\": \"User\",\n  \"namespace\": \"com.streambright\",\n  \"fields\": [{\n    \"name\": \"user_name\",\n    \"type\": \"string\",\n    \"doc\": \"User name of the user\"\n  }, {\n    \"name\": \"age\",\n    \"type\": \"int\",\n    \"doc\": \"Age of the user\"\n  }, {\n    \"name\": \"weight\",\n    \"type\": \"float\",\n    \"doc\": \"Weight of the user\"\n  }, {\n    \"name\": \"address\",\n    \"type\": {\n      \"type\": \"record\",\n      \"name\": \"Address\",\n      \"fields\": [{\n        \"name\": \"street_address\",\n        \"type\": \"string\"\n      }, {\n        \"name\": \"city\",\n        \"type\": \"string\"\n      }]\n    }\n  }],\n  \"doc:\": \"Nothing to see here...\"\n}");
    User user = new User();
    user.setUserName("Tibi Kovacs");
    user.setAge(25);
    user.setWeight(((float) 32.12));
    user.setAddress(new Address("FoxiMaxi St","Budapest"));
    SpecificDatumWriter<User> avroEventWriter = new SpecificDatumWriter<User>(schema);
    EncoderFactory avroEncoderFactory = EncoderFactory.get();
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    BinaryEncoder binaryEncoder = avroEncoderFactory.binaryEncoder(stream, null);
    avroEventWriter.write(user, binaryEncoder);
    binaryEncoder.flush();
    IOUtils.closeQuietly(stream);
    byte[] m = stream.toByteArray();

    FileOutputStream fos = new FileOutputStream("/full/path/data/test3.java.avro");
    fos.write(m);
    fos.close();