Skip to content

Failing @JsonMerge with a custom Map #4922

@nlisker

Description

@nlisker

Continuation of #4783.

import java.util.HashMap;
import java.util.Map;

import com.fasterxml.jackson.annotation.JsonMerge;
import com.fasterxml.jackson.databind.json.JsonMapper;

interface MyMap<K, V> extends Map<K, V> {}

class MapImpl<K, V> extends HashMap<K, V> implements MyMap<K, V> {}

class MapUtils {
	
	static <K, V> MyMap<K, V> createMyMap() {
		return new MapImpl<K, V>();
	}
}

class MergeMap {

	@JsonMerge // either here
	MyMap<Integer, String> map = MapUtils.createMyMap();
	@JsonMerge // or here
	public MyMap<Integer, String> getMap() {
		System.out.println("getMap");
		return map;
	}
	
	@Override
	public String toString() {
		return map.toString();
	}
	
	public static void main(String[] args) throws Exception {
		JsonMapper MAPPER = JsonMapper.builder().build();

		var merge = new MergeMap();
		merge.getMap().put(3, "ADS");
		System.out.println(merge);

		System.out.println(" == serializing --");

		var string = MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(merge);
		System.out.println(string);

		System.out.println(" == deserializing --");

		var merge2 = MAPPER.readValue(string, MergeMap.class);

		System.out.println(" == checking --");

		System.out.println(merge2);
	}
}

This fails in 2.18.2 with

getMap
{3=ADS}
 == serializing --
getMap
{
  "map" : {
    "3" : "ADS"
  }
}
 == deserializing --
Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot find a deserializer for non-concrete Map type [map type; class example.MyMap, [simple type, class java.lang.Integer] -> [simple type, class java.lang.String]]
 at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 1, column: 1]
	at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67)
	at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1888)
	at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:321)
	at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:284)
	at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:174)
	at com.fasterxml.jackson.databind.DeserializationContext.findNonContextualValueDeserializer(DeserializationContext.java:659)
	at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.resolve(BeanDeserializerBase.java:552)
	at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:347)
	at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:284)
	at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:174)
	at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:669)
	at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:5048)
	at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4918)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3860)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3828)
	at example.MergeMap.main(MergeMap.java:49)

I'm not sure where @JsonMerge should be placed - on the field or on the getter, but both failed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    2.18Issues planned at 2.18 or laterhas-failing-testIndicates that there exists a test case (under `failing/`) to reproduce the issue

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions