Skip to content

No _valueDeserializer assigned when @JacksonXmlProperty.localName and field name have the same name. #274

Closed
@billoneil

Description

@billoneil

I'm not sure exactly how this was tracked down but our XML serializer started breaking between version 2.8.7 and 2.8.8 with a

Exception in thread "main" com.fasterxml.jackson.databind.exc.MismatchedInputException: No _valueDeserializer assigned
 at [Source: (StringReader); line: 4, column: 32] (through reference chain: JacksonTest$RootObject["Event"]->JacksonTest$Event["EventId"])

It appears the actual change was in jackson-databind-2.8.7-2.8.8 since there are no notable changes in jackson-dataformat-xml-2.8.7-2.8.8 but seems related to the XML annotations. Here is the best example I could come up with to reproduce.

public class JacksonTest {
	private static final String XML =
		"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + 
		"<dataroot xmlns:od=\"urn:schemas-microsoft-com:officedata\" generated=\"2017-06-07T10:11:20\">\n" + 
		"    <Event>\n" + 
		"        <EventId>34906566143035</EventId>\n" + 
		"    </Event>\n" + 
		"</dataroot>";
	
	static class Event {
	       @JacksonXmlProperty(localName = "EventId")
		private String EventId;

		public String getEventId() {
			return EventId;
		}

		public void setEventId(String eventId) {
			this.EventId = eventId;
		}

	}
	
	@JacksonXmlRootElement(localName = "dataroot")
	static class RootObject {
	    @JacksonXmlProperty(localName = "Event")
	    Event event;
	    
	    @JacksonXmlProperty(localName = "generated")
	    String generated;
	}

	
	public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {
		JacksonXmlModule module = new JacksonXmlModule();
        XmlFactory factory = new XmlFactory();
        XMLOutputFactory outputFactory = new WstxOutputFactory();
        //fix default namespace issue
        outputFactory.setProperty("javax.xml.stream.isRepairingNamespaces", true);

        //Woodstox is the recommended Stax XML API implementation by fasterXml/Jackson
        factory.setXMLOutputFactory(outputFactory);
        factory.setXMLInputFactory(new WstxInputFactory());

	XmlMapper xm = new XmlMapper(factory, module);
	// serialization features
        xm.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        xm.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
	// deserialization features
        xm.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
        //this is for deserialization only and means we don't need to camelCase  xml property names
        xm.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES);

        // enable JAXB as primary introspector
        AnnotationIntrospector jaxbIntrospector = new JaxbAnnotationIntrospector(xm.getTypeFactory());
        AnnotationIntrospector jacksonXmlIntrospector = new JacksonXmlAnnotationIntrospector();
        AnnotationIntrospector pair = new AnnotationIntrospectorPair(jaxbIntrospector, jacksonXmlIntrospector);
        xm.setAnnotationIntrospector(pair);
        
        RootObject obj = xm.readValue(XML, new TypeReference<RootObject>() {});
	}
}

However, commenting out the XML annotation will work.

	static class Event {
	        //@JacksonXmlProperty(localName = "EventId")
		private String EventId;

		public String getEventId() {
			return EventId;
		}

		public void setEventId(String eventId) {
			this.EventId = eventId;
		}
	}

Removing the setter and keeping the annotation will also work.

	static class Event {
	        @JacksonXmlProperty(localName = "EventId")
		private String EventId;

		public String getEventId() {
			return EventId;
		}
	}

Fixing the case of the field will also work.

	static class Event {
	       @JacksonXmlProperty(localName = "EventId")
		private String eventId;

		public String getEventId() {
			return eventId;
		}

		public void setEventId(String eventId) {
			this.eventId = eventId;
		}
	}

And finally commenting out MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES seems to work.

//xm.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES);

This issue only appears to happen when the field name and annotation names match AND there is a setter. From version 2.8.8+ this throws an exception. I can fix this on our end with any of the mentioned fixes just thought I would mention it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions