Uploaded image for project: 'Apache Avro'
  1. Apache Avro
  2. AVRO-2216

GenericData toString generates invalid JSON when map keys are not Strings

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Major
    • Resolution: Fixed
    • 1.9.0
    • 1.9.0
    • java
    • None

    Description

      toString() method for records with maps that have non String Keys generates wrong Json:

      This code:

      Schema intMapSchema = new Schema.Parser().parse("{\"type\": \"map\", \"values\": \"string\", \"java-key-class\" : \"java.lang.Integer\"}");
      Field intMapField = new Field("intMap", Schema.createMap(intMapSchema), null, null);
      Schema decMapSchema = new Schema.Parser().parse("{\"type\": \"map\", \"values\": \"string\", \"java-key-class\" : \"java.math.BigDecimal\"}");
      Field decMapField = new Field("decMap", Schema.createMap(decMapSchema), null, null);
      Schema boolMapSchema = new Schema.Parser().parse("{\"type\": \"map\", \"values\": \"string\", \"java-key-class\" : \"java.lang.Boolean\"}");
      Field boolMapField = new Field("boolMap", Schema.createMap(decMapSchema), null, null);
      Schema fileMapSchema = new Schema.Parser().parse("{\"type\": \"map\", \"values\": \"string\", \"java-key-class\" : \"java.io.File\"}");
      Field fileMapField = new Field("fileMap", Schema.createMap(decMapSchema), null, null);
      Schema schema = Schema.createRecord("my_record", "doc", "mytest", false);
      schema.setFields(Arrays.asList(intMapField,decMapField,boolMapField,fileMapField));
      
      HashMap<Integer, String> intPair =  new HashMap<>();
      intPair.put(1, "one");
      intPair.put(2, "two");
      
      HashMap<java.math.BigDecimal, String> decPair =  new HashMap<>();
      decPair.put(java.math.BigDecimal.valueOf(1), "one");
      decPair.put(java.math.BigDecimal.valueOf(2), "two");
      
      HashMap<Boolean, String> boolPair =  new HashMap<>();
      boolPair.put(true, "isTrue");
      boolPair.put(false, "isFalse");
      boolPair.put(null, null);
      
      HashMap<java.io.File, String> filePair =  new HashMap<>();
      java.io.File f = new java.io.File( getClass().getResource("/mapTestFile.txt").toURI() );
      filePair.put(f, "File");
      
      GenericRecord r = new GenericData.Record(schema);
      r.put(intMapField.name(), intPair);
      r.put(decMapField.name(), decPair);
      r.put(boolMapField.name(), boolPair);
      r.put(fileMapField.name(), filePair);
      
      String json = r.toString();
      

      Would generate the following json:

      {"intMap": {1: "one", 2: "two"}, "decMap": {2: "two", 1: "one"}, "boolMap": {null: null, false: "isFalse", true: "isTrue"}, "fileMap": {/workspace/avro/lang/java/avro/target/test-classes/mapTestFile.txt: "File"}}

      It's missing double quotes for all keys.

      Note that I used classes that are considered as Stringable by ReflectData (plus Integer.class ) and thus, would be able to be serializable.

      This change to force the use of Strings always for Map Keys should be enough to fix this error.

       

      Attachments

        Issue Links

          Activity

            People

              dkulp Daniel Kulp
              alago Alberto Lago
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: