You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by Zoran Regvart <zo...@regvart.com> on 2019/12/02 15:10:01 UTC

Configuring Jackson for java.time

Hi Ron,
for Jackson you need to add support for Java 8+ features explicitly.

Have a look at how to do it here:

https://github.com/FasterXML/jackson-modules-java8

Jackson JSON data format has a `objectMapper`[2] property that you can
use to set the customized ObjectMapper.

zoran

[2] https://camel.apache.org/components/latest/json-jackson-dataformat.html

On Mon, Dec 2, 2019 at 6:21 AM Ron Cecchini <ro...@comcast.net> wrote:
>
> TL;DR: unmarshalling JSON to POJO with Jackson is no longer working on a java.time.OffsetDateTime since migrating to Camel 3.0.  java.util.Date still works fine though.
>
> Ok, after 2 days of googling and trying all manner of sorcery (except for sacrificing a chicken... maybe I should?), I'm waving the white flag on this one...
>
> Basically, I had worked through all the migration stuff.  I also updated Spring Boot to 2.2.1.RELEASE, and updated all the *-starter dependencies, etc.  Everything was working great.
>
> Eventually I uncommented some code I hadn't been using for a while - and that's when the "fun" began...
>
> The input to the route in question is a JSON array upon which I do a .split().jsonpathWriteAsString("$") and eventually an .unmarshal(pojoJson) where 'pojoJson' is:
>
>     JacksonDataFormat pojoJson = new JacksonDataFormat(MyPojo.class);
>
> Things were working fantastic before the migration, but now I get:
>
>     com.fasterxml.jackson.databind.exc.InvalidDefinitionException:
>     Cannot construct instance of `java.time.OffsetDateTime` (no Creators, like default construct, exist):
>     no String-argument constructor/factory method to deserialize from String value ('2019-11-14T04:41:33.302711Z')
>
> Googling revealed all kinds of stuff related to Jackson and Java 8 date/times posted over the last few years.
>
> I tried a few of the suggestions, including adding several Jackson-specific dependencies (to go along with 'org.apache.camel.springboot:camel-jackson-starter') - and adding the dependencies in different orders (someone said that could be a factor) - and nothing worked.
>
> Based on a few suggestions, I even created the following @PostConstruct method in my @SpringBootApplication class, and again got the same "no Creators" error:
>
>     @PostConstruct
>     public void setUp ()
>     {
>         context.getGlobalOptions().put("CamelJacksonEnableTypeConverter", "true");
>         context.getGlobalOptions().put("CamelJacksonTypeConverterToPojo", "true");
>
>         objectMapper.registerModule(new JavaTimeModule());
>         objectMapper.registerModule(new JSR310Module());
>         objectMapper.registerModule(new Jdk8Module());
>         objectMapper.findAndRegisterModules();
>     }
>
> I even tried switching jsonpathWriteAsString("$") to jsonpath("$"), setting pojoJson.useMap(), and passing the Map from jsonpath() to unmarshal, and this time got:
>
>     Caused by: org.apache.camel.NoTypeConversionAvailableException:
>     No type converter available to convert from type: java.util.LinkedHashMap to the required type:
>     java.io.InputStream with value [...]
>
> I finally hit on a temporary workaround - going back to using a java.util.Date instead of a java.time.OffsetDateTime - and it again all works great with Camel 3.0.  But eventually I'll probably need to figure out how to use the newer Java date/times.
>
> Thanks for reading this far and helping me figure out where I went wrong...
>
> > On November 28, 2019 at 2:09 PM Ron Cecchini <ro...@comcast.net> wrote:
> >
> >
> > Christmas has come early!
> >
> > There's so much new stuff I'm not even sure what I should be excited about at the moment - but I'm excited!
> >
> > Thank you for all your efforts, guys!
> >
> > (and now I can spend pre-Thanksgiving feasting working through the Migration and eliminating the run-time crashes...)
> >
> > > On November 28, 2019 at 9:12 AM Gregor Zurowski <gr...@list.zurowski.org> wrote:
> > >
> > >
> > > It's finally here - after four release candidates and three milestone
> > > releases, the Camel community announces the immediate availability of
> > > Camel 3.0.0, a new major release with over 1000 new features,
> > > improvements and fixes.
> > >
> > > Please read our migration guide [1] that describes how to upgrade
> > > Camel 2.x applications to Camel 3.0.
> > >
> > > The artifacts are published and ready for you to download [2] either
> > > from the Apache mirrors or from the Central Maven repository. For more
> > > details please take a look at the release notes [3, 4].
> > >
> > > Many thanks to all who made this release possible.
> > >
> > > On behalf of the Camel PMC,
> > > Gregor Zurowski
> > >
> > > [1] https://camel.apache.org/manual/latest/camel-3-migration-guide.html
> > > [1] http://camel.apache.org/download.html
> > > [2] https://camel.apache.org/blog/release-3-0-0.html
> > > [3] https://issues.apache.org/jira/secure/ReleaseNote.jspa?version=12315691&projectId=12311211



-- 
Zoran Regvart

Re: Configuring Jackson for java.time

Posted by Ron Cecchini <ro...@comcast.net>.
Just an update that I did eventually get it.  Sweet blessed relief...

Thanks to Zoran for a pointer which led to the missing crucial piece.

---

As it turns out, it's not enough to simply add the desired time modules to Jackson's ObjectMapper.  You also *have* to add the ObjectMapper to any JacksonDataFormat you create as it has none on it by default.

For anyone interested, this is all you have to do to get Jackson to deserialize the new java.time.* types:

1. Add the Jackson BOM to <dependencyManagement>

<dependency>
  <groupId>com.fasterxml.jackson</groupId>
  <artifactId>jackson-bom</artifactId>
  <version>2.10.0</version>
  <type>pom</type>
  <scope>import</scope>
</dependency>

2. get the Jackon ObjectMapper and set it on a JacksonDataFormat:

@Autowired
private ObjectMapper objectMapper;

JacksonDataFormat myPojoJson = new JacksonDataFormat(MyPojo.class);
myPojoJson.setObjectMapper(objectMapper);

or, even easier, skip the Autowired and

3. have Jackson auto-discover the ObjectMapper:

myPojoJson.setAutoDiscovery(true);

Note: you don't have to register any modules on the ObjectMapper as the needed ones are already registered.

Also, FWIW, setting the following didn't seem to be necessary:

context.getGlobalOptions().put("CamelJacksonEnableTypeConverter", "true");
context.getGlobalOptions().put("CamelJacksonTypeConverterToPojo", "true");

> On December 2, 2019 at 10:10 AM Zoran Regvart <zo...@regvart.com> wrote:
> 
> 
> Hi Ron,
> for Jackson you need to add support for Java 8+ features explicitly.
> 
> Have a look at how to do it here:
> 
> https://github.com/FasterXML/jackson-modules-java8
> 
> Jackson JSON data format has a `objectMapper`[2] property that you can
> use to set the customized ObjectMapper.
> 
> zoran
> 
> [2] https://camel.apache.org/components/latest/json-jackson-dataformat.html
> 
> On Mon, Dec 2, 2019 at 6:21 AM Ron Cecchini <ro...@comcast.net> wrote:
> >
> > TL;DR: unmarshalling JSON to POJO with Jackson is no longer working on a java.time.OffsetDateTime since migrating to Camel 3.0.  java.util.Date still works fine though.
> >
> > Ok, after 2 days of googling and trying all manner of sorcery (except for sacrificing a chicken... maybe I should?), I'm waving the white flag on this one...
> >
> > Basically, I had worked through all the migration stuff.  I also updated Spring Boot to 2.2.1.RELEASE, and updated all the *-starter dependencies, etc.  Everything was working great.
> >
> > Eventually I uncommented some code I hadn't been using for a while - and that's when the "fun" began...
> >
> > The input to the route in question is a JSON array upon which I do a .split().jsonpathWriteAsString("$") and eventually an .unmarshal(pojoJson) where 'pojoJson' is:
> >
> >     JacksonDataFormat pojoJson = new JacksonDataFormat(MyPojo.class);
> >
> > Things were working fantastic before the migration, but now I get:
> >
> >     com.fasterxml.jackson.databind.exc.InvalidDefinitionException:
> >     Cannot construct instance of `java.time.OffsetDateTime` (no Creators, like default construct, exist):
> >     no String-argument constructor/factory method to deserialize from String value ('2019-11-14T04:41:33.302711Z')
> >
> > Googling revealed all kinds of stuff related to Jackson and Java 8 date/times posted over the last few years.
> >
> > I tried a few of the suggestions, including adding several Jackson-specific dependencies (to go along with 'org.apache.camel.springboot:camel-jackson-starter') - and adding the dependencies in different orders (someone said that could be a factor) - and nothing worked.
> >
> > Based on a few suggestions, I even created the following @PostConstruct method in my @SpringBootApplication class, and again got the same "no Creators" error:
> >
> >     @PostConstruct
> >     public void setUp ()
> >     {
> >         context.getGlobalOptions().put("CamelJacksonEnableTypeConverter", "true");
> >         context.getGlobalOptions().put("CamelJacksonTypeConverterToPojo", "true");
> >
> >         objectMapper.registerModule(new JavaTimeModule());
> >         objectMapper.registerModule(new JSR310Module());
> >         objectMapper.registerModule(new Jdk8Module());
> >         objectMapper.findAndRegisterModules();
> >     }
> >
> > I even tried switching jsonpathWriteAsString("$") to jsonpath("$"), setting pojoJson.useMap(), and passing the Map from jsonpath() to unmarshal, and this time got:
> >
> >     Caused by: org.apache.camel.NoTypeConversionAvailableException:
> >     No type converter available to convert from type: java.util.LinkedHashMap to the required type:
> >     java.io.InputStream with value [...]
> >
> > I finally hit on a temporary workaround - going back to using a java.util.Date instead of a java.time.OffsetDateTime - and it again all works great with Camel 3.0.  But eventually I'll probably need to figure out how to use the newer Java date/times.
> >
> > Thanks for reading this far and helping me figure out where I went wrong...
> >
> > > On November 28, 2019 at 2:09 PM Ron Cecchini <ro...@comcast.net> wrote:
> > >
> > >
> > > Christmas has come early!
> > >
> > > There's so much new stuff I'm not even sure what I should be excited about at the moment - but I'm excited!
> > >
> > > Thank you for all your efforts, guys!
> > >
> > > (and now I can spend pre-Thanksgiving feasting working through the Migration and eliminating the run-time crashes...)
> > >
> > > > On November 28, 2019 at 9:12 AM Gregor Zurowski <gr...@list.zurowski.org> wrote:
> > > >
> > > >
> > > > It's finally here - after four release candidates and three milestone
> > > > releases, the Camel community announces the immediate availability of
> > > > Camel 3.0.0, a new major release with over 1000 new features,
> > > > improvements and fixes.
> > > >
> > > > Please read our migration guide [1] that describes how to upgrade
> > > > Camel 2.x applications to Camel 3.0.
> > > >
> > > > The artifacts are published and ready for you to download [2] either
> > > > from the Apache mirrors or from the Central Maven repository. For more
> > > > details please take a look at the release notes [3, 4].
> > > >
> > > > Many thanks to all who made this release possible.
> > > >
> > > > On behalf of the Camel PMC,
> > > > Gregor Zurowski
> > > >
> > > > [1] https://camel.apache.org/manual/latest/camel-3-migration-guide.html
> > > > [1] http://camel.apache.org/download.html
> > > > [2] https://camel.apache.org/blog/release-3-0-0.html
> > > > [3] https://issues.apache.org/jira/secure/ReleaseNote.jspa?version=12315691&projectId=12311211
> 
> 
> 
> -- 
> Zoran Regvart