Uploaded image for project: 'JBoss Enterprise Application Platform'
  1. JBoss Enterprise Application Platform
  2. JBEAP-22263

[GSS](7.4.z) Serialization of a Map fails if the key uses a custom Serializer

XMLWordPrintable

    • False
    • False
    • +
    • Undefined
    • Hide

      Use an adapter for the map:

      public class LocaleJsonbAdapter implements JsonbAdapter<Map<Locale, String>, Map<String, String>> {
          @Override
          public Map<String, String> adaptToJson(final Map<Locale, String> obj) throws Exception {
              final Map<String, String> copy = new LinkedHashMap<>();
              for (Map.Entry<Locale, String> entry : obj.entrySet()) {
                  copy.put(entry.getKey().toLanguageTag(), entry.getValue());
              }
              return copy;
          }
      
          @Override
          public Map<Locale, String> adaptFromJson(final Map<String, String> obj) throws Exception {
              final Map<Locale, String> copy = new LinkedHashMap<>();
              for (Map.Entry<String, String> entry : obj.entrySet()) {
                  copy.put(Locale.forLanguageTag(entry.getKey()), entry.getValue());
              }
              return copy;
          }
      }
      
      Show
      Use an adapter for the map: public class LocaleJsonbAdapter implements JsonbAdapter<Map<Locale, String >, Map< String , String >> { @Override public Map< String , String > adaptToJson( final Map<Locale, String > obj) throws Exception { final Map< String , String > copy = new LinkedHashMap<>(); for (Map.Entry<Locale, String > entry : obj.entrySet()) { copy.put(entry.getKey().toLanguageTag(), entry.getValue()); } return copy; } @Override public Map<Locale, String > adaptFromJson( final Map< String , String > obj) throws Exception { final Map<Locale, String > copy = new LinkedHashMap<>(); for (Map.Entry< String , String > entry : obj.entrySet()) { copy.put(Locale.forLanguageTag(entry.getKey()), entry.getValue()); } return copy; } }
    • Hide

      With the attached maven project just execute test on it:

      unzip issue-map-locale-key.zip
      cd issue-map-locale-key
      mvn clean test
      
      Show
      With the attached maven project just execute test on it: unzip issue-map-locale-key.zip cd issue-map-locale-key mvn clean test

      If you define a custom Serializer for a Locale object like the following:

          public static class LocaleSerializer implements JsonbSerializer<Locale> {
              @Override
              public void serialize(Locale obj, JsonGenerator generator, SerializationContext ctx) {
                  generator.write(obj.toLanguageTag());
              }
          }
      

      And use a Pojo class that contains a Map field with Locale as the key:

      public class TestObject {
        private Map<Locale, String> localeKeyMap;
        ...
      }
      

      If you try to serialize it with current yasson (version 2.0.2 or 1.0.9 included in EAP), like the following code:

              Jsonb jsonb = JsonbBuilder.create(new JsonbConfig()
                      .withSerializers(new LocaleSerializer())
                      .withDeserializers(new LocaleDeserializer()));
              TestObject o = new TestObject();
              o.getLocaleKeyMap().put(Locale.US, "us");
              jsonb.toJson(o);
      

      The following exception is thrown:

      jakarta.json.bind.JsonbException: Unable to serialize property 'values' from test.MapObjectTest.MapObjectLocaleString
      	at org.eclipse.yasson.internal.serializer.ObjectSerializer.serializeInternal(ObjectSerializer.java:71)
      	at org.eclipse.yasson.internal.serializer.AbstractContainerSerializer.serialize(AbstractContainerSerializer.java:107)
      	at org.eclipse.yasson.internal.Marshaller.serializeRoot(Marshaller.java:147)
      	at org.eclipse.yasson.internal.Marshaller.marshall(Marshaller.java:73)
      	at org.eclipse.yasson.internal.Marshaller.marshall(Marshaller.java:101)
      	at org.eclipse.yasson.internal.JsonBinding.toJson(JsonBinding.java:126)
      	at test.MapObjectTest.test1(MapObjectTest.java:95)
      	...
      Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Locale
      	at test.MapObjectTest$LocaleSerializer.serialize(MapObjectTest.java:27)
      	at org.eclipse.yasson.internal.serializer.UserSerializerSerializer.serialize(UserSerializerSerializer.java:53)
      	at org.eclipse.yasson.internal.serializer.AbstractContainerSerializer.serializerCaptor(AbstractContainerSerializer.java:125)
      	at org.eclipse.yasson.internal.serializer.AbstractContainerSerializer.serializeItem(AbstractContainerSerializer.java:194)
      	at org.eclipse.yasson.internal.serializer.MapToEntriesArraySerializer.lambda$serializeContainer(MapToEntriesArraySerializer.java:111)
      	at java.util.HashMap.forEach(HashMap.java:1289)
      	at org.eclipse.yasson.internal.serializer.MapToEntriesArraySerializer.serializeContainer(MapToEntriesArraySerializer.java:106)
      	at org.eclipse.yasson.internal.serializer.MapSerializer.serializeInternal(MapSerializer.java:156)
      	at org.eclipse.yasson.internal.serializer.MapSerializer.serializeInternal(MapSerializer.java:27)
      	at org.eclipse.yasson.internal.serializer.AbstractContainerSerializer.serialize(AbstractContainerSerializer.java:107)
      	at org.eclipse.yasson.internal.serializer.AbstractContainerSerializer.serializerCaptor(AbstractContainerSerializer.java:125)
      	at org.eclipse.yasson.internal.serializer.ObjectSerializer.marshallProperty(ObjectSerializer.java:121)
      	at org.eclipse.yasson.internal.serializer.ObjectSerializer.serializeInternal(ObjectSerializer.java:69)
      	... 38 more
      

              rhn-support-rmartinc Ricardo Martin Camarero
              rhn-support-rmartinc Ricardo Martin Camarero
              Votes:
              0 Vote for this issue
              Watchers:
              6 Start watching this issue

                Created:
                Updated:
                Resolved: