0

I am working with Reactive X on Android.

When I call this observable :

fun getTalks() : Observable<List<Talk>> {
    return Observable.create<List<Talk>> {
        val text = resources.openRawResource(R.raw.sample).bufferedReader().use { it.readText() }
        val mapper = jacksonObjectMapper()
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
        mapper.readValue(text)
    }
}

A get an error at runtime

2018-10-04 15:28:19.314 28269-28269/io.bdx.speaktimer W/Java7Support: Unable to load JDK7 types (annotations, java.nio.file.Path): no Java7 support added
2018-10-04 15:28:19.421 28269-28290/io.bdx.speaktimer E/TalksActivity: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `kotlin.Unit` out of START_ARRAY token
 at [Source: (StringReader); line: 1, column: 1]
2018-10-04 15:28:19.423 28269-28290/io.bdx.speaktimer W/System.err: io.reactivex.exceptions.CompositeException: 1 exceptions occurred. 
2018-10-04 15:28:19.423 28269-28290/io.bdx.speaktimer W/System.err:     at io.reactivex.internal.observers.LambdaObserver.onError(LambdaObserver.java:80)
2018-10-04 15:28:19.423 28269-28290/io.bdx.speaktimer W/System.err:     at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.checkTerminated(ObservableObserveOn.java:281)
2018-10-04 15:28:19.423 28269-28290/io.bdx.speaktimer W/System.err:     at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.drainNormal(ObservableObserveOn.java:172)
2018-10-04 15:28:19.423 28269-28290/io.bdx.speaktimer W/System.err:     at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.run(ObservableObserveOn.java:255)
2018-10-04 15:28:19.423 28269-28290/io.bdx.speaktimer W/System.err:     at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:66)
2018-10-04 15:28:19.423 28269-28290/io.bdx.speaktimer W/System.err:     at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:57)
2018-10-04 15:28:19.423 28269-28290/io.bdx.speaktimer W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:266)
2018-10-04 15:28:19.423 28269-28290/io.bdx.speaktimer W/System.err:     at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
2018-10-04 15:28:19.423 28269-28290/io.bdx.speaktimer W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
2018-10-04 15:28:19.423 28269-28290/io.bdx.speaktimer W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
2018-10-04 15:28:19.423 28269-28290/io.bdx.speaktimer W/System.err:     at java.lang.Thread.run(Thread.java:764)
2018-10-04 15:28:19.423 28269-28290/io.bdx.speaktimer W/System.err:   ComposedException 1 :
2018-10-04 15:28:19.423 28269-28290/io.bdx.speaktimer W/System.err:     com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `kotlin.Unit` out of START_ARRAY token
2018-10-04 15:28:19.423 28269-28290/io.bdx.speaktimer W/System.err:  at [Source: (StringReader); line: 1, column: 1]
2018-10-04 15:28:19.423 28269-28290/io.bdx.speaktimer W/System.err:     at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1343)
2018-10-04 15:28:19.423 28269-28290/io.bdx.speaktimer W/System.err:     at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1139)
2018-10-04 15:28:19.423 28269-28290/io.bdx.speaktimer W/System.err:     at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1093)
2018-10-04 15:28:19.423 28269-28290/io.bdx.speaktimer W/System.err:     at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromArray(BeanDeserializerBase.java:1461)
2018-10-04 15:28:19.423 28269-28290/io.bdx.speaktimer W/System.err:     at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:185)
2018-10-04 15:28:19.423 28269-28290/io.bdx.speaktimer W/System.err:     at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:161)
2018-10-04 15:28:19.423 28269-28290/io.bdx.speaktimer W/System.err:     at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013)
2018-10-04 15:28:19.423 28269-28290/io.bdx.speaktimer W/System.err:     at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3023)
2018-10-04 15:28:19.423 28269-28290/io.bdx.speaktimer W/System.err:     at io.bdx.speaktimer.TalksActivity$getTalks$1.subscribe(TalksActivity.kt:108)
2018-10-04 15:28:19.423 28269-28290/io.bdx.speaktimer W/System.err:     at io.reactivex.internal.operators.observable.ObservableCreate.subscribeActual(ObservableCreate.java:40)
2018-10-04 15:28:19.423 28269-28290/io.bdx.speaktimer W/System.err:     at io.reactivex.Observable.subscribe(Observable.java:12090)
2018-10-04 15:28:19.423 28269-28290/io.bdx.speaktimer W/System.err:     at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96)
2018-10-04 15:28:19.423 28269-28290/io.bdx.speaktimer W/System.err:     at io.reactivex.android.schedulers.HandlerScheduler$ScheduledRunnable.run(HandlerScheduler.java:119)
2018-10-04 15:28:19.423 28269-28290/io.bdx.speaktimer W/System.err:     at android.os.Handler.handleCallback(Handler.java:790)
2018-10-04 15:28:19.423 28269-28290/io.bdx.speaktimer W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:99)
2018-10-04 15:28:19.423 28269-28290/io.bdx.speaktimer W/System.err:     at android.os.Looper.loop(Looper.java:164)
2018-10-04 15:28:19.423 28269-28290/io.bdx.speaktimer W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:6494)
2018-10-04 15:28:19.423 28269-28290/io.bdx.speaktimer W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
2018-10-04 15:28:19.423 28269-28290/io.bdx.speaktimer W/System.err:     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
2018-10-04 15:28:19.423 28269-28290/io.bdx.speaktimer W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

Here is my sample.json file

[
{
    "@class": "voxxrin.companion.domain.Presentation",
    "creationDate": null,
    "updateDate": "2018-09-24T21:13:16.567Z",
    "eventId": "bdxio18",
    "title": "Faut-il pousser mémé dans les applis ?",
    "summary": "<p>Je me présente Arthur Retrou - UX Designer. J'adore ma grand-mère pourtant je ne compte plus les appels pour l'aider à démarrer un Skype. En effet, nos parents et grand-parents investissent de plus en plus les applications, mais pas sans difficultés.\nÀ travers la création de plusieurs interfaces pour personnes âgées, je me suis confronté aux problématiques de cette silver économie. Avec des conseils simples et des astuces de design applicables à tout types de projets, je dévoile non sans humour les secrets pour concevoir des maquettes ergonomiques et adaptées.</p>\n",
    "speakers": [
        {
            "@class": "voxxrin.companion.domain.Speaker",
            "creationDate": null,
            "updateDate": "2018-09-24T21:13:12.966Z",
            "eventId": "bdxio18",
            "name": "Arthur Retrou",
            "firstName": "Arthur",
            "lastName": "Retrou",
            "company": "Dernier Cri",
            "bio": "Arthur Retrou, designer UX chez Dernier Cri. J'habite Lille et j'adore les barbecues, la paëlla, la pâte à prout et les festoches !",
            "avatarUrl": "https://scontent-cdg2-1.xx.fbcdn.net/v/t31.0-8/19055828_10212723864355964_5048654608666975793_o.jpg?_nc_cat=0&oh=815b0264049195fc01fa468831ea4883&oe=5C0AD6A9",
            "twitterId": "@derniercriio",
            "uuid": "c00a15663283cc47dea309484913dd47c5c7b93c",
            "_id": "5ba95365e4b0b618af601b1b"
        }
    ],
    "location": {
        "@class": "voxxrin.companion.domain.Room",
        "creationDate": null,
        "updateDate": "2018-09-24T21:13:10.855Z",
        "eventId": "bdxio18",
        "name": "N/C",
        "fullName": "N/C",
        "_id": "5ba95365e4b0b618af601b19"
    },
    "from": "2018-11-09T09:00:00.000Z",
    "to": "2018-11-09T10:00:00.000Z",
    "kind": "Conference",
    "externalId": "IZA-1897",
    "favorite": false,
    "reminded": false,
    "favoriteCount": 3,
    "remindMeCount": 2,
    "releasedContents": [],
    "_id": "5ba95366e4b0b618af601b50"
},
{
    "@class": "voxxrin.companion.domain.Presentation",
    "creationDate": null,
    "updateDate": "2018-09-24T21:13:16.685Z",
    "eventId": "bdxio18",
    "title": "Développeurs, n'estimez plus vos tâches ! #noEstimates",
    "summary": "<p>On le sait tous, estimer est à la fois difficile et coûteux et combien de fois vos tâches ont pris plus de temps que prévues? L'estimation est aujourd'hui l'une des méthodes de prédilection pour la prise de décision ainsi que l'évaluation des dates de release de nos projets... mais aujourd'hui il existe une alternative: ne plus estimer ses tâches!</p>\n<p>Venez découvrir ce retour d'expérience sur la mise en place du #noEstimates sur une équipe de développement depuis plus d'un an. Vous verrez quelles sont les clés ainsi que les outils nécessaires à sa mise en place.</p>\n",
    "speakers": [
        {
            "@class": "voxxrin.companion.domain.Speaker",
            "creationDate": null,
            "updateDate": "2018-09-24T21:13:13.197Z",
            "eventId": "bdxio18",
            "name": "Julien Topçu",


...


            "firstName": "Elvina",
            "lastName": "Valieva",
            "company": "PeopleDoc",
            "bio": "Loves JavaScript and Open Source.",
            "avatarUrl": "https://avatars2.githubusercontent.com/u/8288415?s=400&u=2886b74b0c6ad5838fa885a7980d90f749f830a5&v=4",
            "twitterId": "elvinanananana",
            "uuid": "df03db8f7736c82c3e7b35efffb9b9e73f857e33",
            "_id": "5ba95366e4b0b618af601b4f"
        }
    ],
    "location": {
        "@class": "voxxrin.companion.domain.Room",
        "creationDate": null,
        "updateDate": "2018-09-24T21:13:10.855Z",
        "eventId": "bdxio18",
        "name": "N/C",
        "fullName": "N/C",
        "_id": "5ba95365e4b0b618af601b19"
    },
    "from": "2018-11-09T19:00:00.000Z",
    "to": "2018-11-09T20:00:00.000Z",
    "kind": "Lightning talk",
    "externalId": "OWS-5521",
    "favorite": false,
    "reminded": false,
    "favoriteCount": 2,
    "remindMeCount": 1,
    "releasedContents": [],
    "_id": "5ba95366e4b0b618af601b7a"
}
]

I have seen this answer https://stackoverflow.com/a/50492616/2683000 which advice to wrap my content inside an Object but I cannot because I only read files.

Any idea?

EDIT

The list of talks (List<Talk>) is a list of this object:

import java.io.Serializable

data class Talk(
    val eventId: String,
    val title: String,
    val summary: String,
    val from: String,
    val to: String
) : Serializable
psv
  • 3,147
  • 5
  • 32
  • 67

1 Answers1

0

I finally found the solution.

The problem was to tell to jackson exactly what it should expect with the typeFactory.

Here is how to deserialize an ArrayList of custom objects:

val text = resources.openRawResource(R.raw.sample).bufferedReader().use { it.readText() }
val typeFactory = mapper.typeFactory
val collectionType = typeFactory.constructCollectionType(ArrayList::class.java, Talk::class.java)
val resultList = mapper.readValue<List<Talk>>(text, collectionType)
psv
  • 3,147
  • 5
  • 32
  • 67
  • I don't think this was needed, only making sure you made it clear what the type would be so that type inference for the lambda and for the call to readValue made the right decisions. ReadValue when called with inferable or explicit type would do this for you. You had a lambda trying to infer return type from a method who was trying to infer its return type. So you hacked around it, but with more than necessary – Jayson Minard Oct 14 '18 at 15:50
  • I invite you to test by yourself, adding `mapper.readValue>` only was not working at runtime (compilation OK). – psv Oct 14 '18 at 15:54