intercom/intercom-java

Intercom-java SDK is not compatible with recent versions of Jackson

Opened this issue · 7 comments

If you use Jackson v 2.16.x, you get this exception (in this case, updating a Company). Reverting to Jackson 2.15.4 works.

Caused by: io.intercom.api.IntercomException: Local exception calling [https://api.intercom.io//companies]. Check connectivity and settings. [Unrecognized field "type" (class io.intercom.api.TypedData), not marked as ignorable (0 known properties: ])
 at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 1, column: 288] (through reference chain: io.intercom.api.Company["tags"]->io.intercom.api.TagCollection["tags"]->java.util.ArrayList[0]->io.intercom.api.TypedData["type"])]
	at io.intercom.api.HttpClient.throwLocalException(HttpClient.java:124)
	at io.intercom.api.HttpClient.executeHttpMethod(HttpClient.java:112)
	at io.intercom.api.HttpClient.post(HttpClient.java:100)
	at io.intercom.api.DataResource.update(DataResource.java:35)
	at io.intercom.api.Company.update(Company.java:51)
	at com.orbitkit.houston.intercom.CompanyUpdater.update(CompanyUpdater.java:107)
	at com.orbitkit.houston.intercom.IntercomUpdateOrgTask.run2(IntercomUpdateOrgTask.java:35)
	at com.orbitkit.houston.util.task.Task.run(Task.java:26)
	at com.orbitkit.remote.errand.RunTask.run(RunTask.java:23)
	at com.orbitkit.remote.Errand.lambda$start$0(Errand.java:132)
	... 4 more
Caused by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "type" (class io.intercom.api.TypedData), not marked as ignorable (0 known properties: ])
 at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 1, column: 288] (through reference chain: io.intercom.api.Company["tags"]->io.intercom.api.TagCollection["tags"]->java.util.ArrayList[0]->io.intercom.api.TypedData["type"])
	at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:61)
	at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:1153)
	at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:2224)
	at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1719)
	at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1697)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:316)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:177)
	at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer._deserializeFromArray(CollectionDeserializer.java:359)
	at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:244)
	at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:28)
	at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:138)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:310)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:177)
	at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:138)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:310)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:177)
	at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:342)
	at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4899)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3846)
	at io.intercom.api.HttpClient.readEntity(HttpClient.java:192)
	at io.intercom.api.HttpClient.handleSuccess(HttpClient.java:176)
	at io.intercom.api.HttpClient.runRequest(HttpClient.java:153)
	at io.intercom.api.HttpClient.executeHttpMethod(HttpClient.java:110)
	... 12 more

Version info

  • intercom-java version: 2.8.2
  • Java version: 21
cies commented

We have the same issue. We upgraded to Jackson 2.17.1 and boom:

Local exception calling [https://api.intercom.io//users]. Check connectivity and settings. [Unrecognized field "type" (class io.intercom.api.TypedData), not marked as ignorable (0 known properties: ])
at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 1, column: 317] (through reference chain: io.intercom.api.User["companies"]->io.intercom.api.CompanyCollection["companies"]->java.util.ArrayList[0]->io.intercom.api.TypedData["type"])]
at io.intercom.api.HttpClient.throwLocalException(HttpClient.java:124)
at io.intercom.api.HttpClient.executeHttpMethod(HttpClient.java:112)
at io.intercom.api.HttpClient.post(HttpClient.java:100)
at io.intercom.api.DataResource.create(DataResource.java:25)
at io.intercom.api.User.create(User.java:50)
at utils.thirdpartyintegration.intercom.IntercomClient.upsertOrganizationAndUser(IntercomClient.kt:41)
at models.organization.NewOrganizationService.initializeOrganizerAccount(NewOrganizationService.kt:135)
at controllers.backstage.ui.SignUp.initializeOrganization(SignUp.kt:322)
at controllers.backstage.ui.SignUp.handlePostStep3(SignUp.kt:297)
at controllers.backstage.ui.SignUp.wizard(SignUp.kt:170)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
at play.mvc.ActionInvoker.invoke(ActionInvoker.java:448)
at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:443)
at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:431)
at play.mvc.ActionInvoker.invoke(ActionInvoker.java:140)
at play.server.netty3.PlayHandler$Netty3Invocation.execute(PlayHandler.java:284)
at play.server.netty3.PlayHandler$Netty3Invocation.lambda$run$0(PlayHandler.java:252)
at play.db.jpa.JPA.withTransaction(JPA.java:226)
at play.db.jpa.JPA.withinFilter(JPA.java:181)
at play.server.netty3.PlayHandler$Netty3Invocation.run(PlayHandler.java:251)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.base/java.lang.Thread.run(Unknown Source)
by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "type" (class io.intercom.api.TypedData), not marked as ignorable (0 known properties: ])
at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 1, column: 317] (through reference chain: io.intercom.api.User["companies"]->io.intercom.api.CompanyCollection["companies"]->java.util.ArrayList[0]->io.intercom.api.TypedData["type"])
at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:61)
at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:1153)
at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:2241)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1793)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1771)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:316)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:177)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer._deserializeFromArray(CollectionDeserializer.java:361)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:246)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:30)
at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:138)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:310)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:177)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:310)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:177)
at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:342)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4905)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3848)
at io.intercom.api.HttpClient.readEntity(HttpClient.java:192)
at io.intercom.api.HttpClient.handleSuccess(HttpClient.java:176)
at io.intercom.api.HttpClient.runRequest(HttpClient.java:153)
at io.intercom.api.HttpClient.executeHttpMethod(HttpClient.java:110)
... 27 more

JDK17
intercom-java 2.8.2

cies commented

Probably Jackson's objectMapper has different defaults: you can probably configure the objectMapper to work in the old way (ignoring properties that cannot be mapped).

cies commented

Intercom specifies com.fasterxml.jackson.core:jackson-core:2.9.10 but in with the defaults that version is often bumped if other dependecies also require Jackson (or when Jackson is required directly by the project).

We had to strict-specify the Jackson version for our project with:

implementation("com.fasterxml.jackson.core:jackson-core") { version { strictly("2.15.4") } }

We are also having this issue after upgrading to Jackson > 2.16.0

I did some bisecting with jackson-databind and the problem seems to have been introduced by FasterXML/jackson-databind#3952 (to resolve FasterXML/jackson-databind#3950 )

The same exception occurs when calling User.find with Jackson 2.17.x.
The temporary solution was to downgrade dependencies so that Jackson 2.15.x used (rather than evicted), but that's not a long-term resolution.

If @cies is correct about this being fixable with a Jackson ObjectMapper configuration change, then perhaps the fix could be some one-liner in the MapperSupport code which seems to initialize the single objectMapper instance that gets used by HttpClient.readEntity?

private ObjectMapper configure(ObjectMapper om) {
return om.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, true)
.configure(SerializationFeature.INDENT_OUTPUT, true)
.configure(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, false)
.configure(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS, false)
.registerModule(customAttributeModule());
}

As paying Intercom customers, we received a response from their helpdesk regarding this issue:

Okay, I have an update from the team!
For the Java SDK, there are no planned updates at this time due to it being in maintenance mode as I said. So our recommendation is that you use regular API endpoints as opposed to the SDK wrapper. I can see you're looking to use it though, so what I can do for you here is pass this feedback to the team to let them know you're interested in using that SDK. It may seem self-explanatory, but could you give me a bit more insight into why this would be helpful for your team in particular? Any extra info I can pass along to the R&D team is certainly helpful as they prioritise and build new features 🙏

I hope it is helpful.

Would shading Jackson be a possibility ?