Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't deserialize a serialized DateTimeZone with default typing #82

Closed
strmer15 opened this issue Mar 3, 2016 · 4 comments
Closed

Can't deserialize a serialized DateTimeZone with default typing #82

strmer15 opened this issue Mar 3, 2016 · 4 comments
Milestone

Comments

@strmer15
Copy link

strmer15 commented Mar 3, 2016

Trying to serialize a DateTimeZone instance, then deserialize it back afterwards; it always fails. Looks like it's due to the fact that there is no type mapping for CachedDateTimeZone (indeed for any of the subclasses of DateTimeZone) and no String constructor, combined with our project's use of default typing on serialized objects.

package com.rw;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.joda.JodaModule;
import org.joda.time.DateTimeZone;
import org.junit.Assert;
import org.junit.Test;

public class TestTimeZone {

    @Test
    public void testTimeZoneSerialization() throws Exception {
        final ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);

        objectMapper.registerModule(new JodaModule());

        final DateTimeZone timeZone = DateTimeZone.forID("America/New_York");
        final String json = objectMapper.writeValueAsString(timeZone);

        final DateTimeZone timeZoneRead = objectMapper.readValue(json, DateTimeZone.class);

        Assert.assertNotNull(timeZoneRead.getID());
        Assert.assertEquals("America/New_York", timeZoneRead.getID());
    }
}

Result:

com.fasterxml.jackson.databind.JsonMappingException: Can not instantiate value of type [simple type, class org.joda.time.tz.CachedDateTimeZone] from String value ('America/New_York'); no single-String constructor/factory method
 at [Source: ["org.joda.time.tz.CachedDateTimeZone","America/New_York"]; line: 1, column: 40]

Obviously, a simple workaround is to create a mix-in just for DateTimeZone that disables typing only for it. The following test passes:

package com.rw;

import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.joda.JodaModule;
import org.joda.time.DateTimeZone;
import org.junit.Assert;
import org.junit.Test;

public class TestTimeZone {

    @Test
    public void testTimeZoneSerialization() throws Exception {
        final ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        objectMapper.addMixIn(DateTimeZone.class, DateTimeZoneMixin.class);

        objectMapper.registerModule(new JodaModule());

        final DateTimeZone timeZone = DateTimeZone.forID("America/New_York");
        final String json = objectMapper.writeValueAsString(timeZone);

        final DateTimeZone timeZoneRead = objectMapper.readValue(json, DateTimeZone.class);

        Assert.assertNotNull(timeZoneRead.getID());
        Assert.assertEquals("America/New_York", timeZoneRead.getID());
    }

    @JsonTypeInfo(use = JsonTypeInfo.Id.NONE)
    public interface DateTimeZoneMixin {

    }
}
@cowtowncoder
Copy link
Member

Thank you for reporting this. Is this reproducible on 2.7.2?

@strmer15
Copy link
Author

strmer15 commented Mar 4, 2016

Yep - sorry, should have mentioned which versions I tested against, here's the POM:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>com.rw</groupId>
    <artifactId>test-jackson-joda</artifactId>
    <version>1.0</version>

    <dependencies>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.7.2</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.7.2</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.7.2</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.7.2</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-joda</artifactId>
            <version>2.7.2</version>
        </dependency>
        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
            <version>2.9.2</version>
        </dependency>
    </dependencies>
</project>

@cowtowncoder
Copy link
Member

No prob, thanks!

@cowtowncoder cowtowncoder added this to the 2.7.3 milestone Mar 5, 2016
@cowtowncoder
Copy link
Member

Just needed to basically force type information to use abstract type DateTimeZone; deserializer knows how to deal with that type. Will be included in 2.7.3, as well as 2.6.6 when they get released.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants