intercom / intercom-java

Java bindings for the Intercom API
https://developers.intercom.io/reference
Apache License 2.0
64 stars 68 forks source link

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

Open stickfigure opened 8 months ago

stickfigure commented 8 months ago

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

cies commented 5 months ago

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 5 months ago

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 5 months ago

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") } }
froque commented 2 months ago

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 https://github.com/FasterXML/jackson-databind/pull/3952 (to resolve https://github.com/FasterXML/jackson-databind/issues/3950 )

mertant commented 2 weeks ago

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? https://github.com/intercom/intercom-java/blob/6b4765c0175ece7ef31489094664191a9a8554b8/intercom-java/src/main/java/io/intercom/api/MapperSupport.java#L18-L24