2

I'm observing what appears to be some wierd behavior with the Jackson JsonParser, specifically, capturing a correct JsonPointer while in an array.

Given the following JSON snippet:

[
    {
        "name": "a",
        "children": [
            {
                "name": "b"
            },
            {
                "name": "c"
            },
            {
                "name": "d"
            }
        ]
    },
    {
        "name": "e",
        "children": [
            {
                "name": "f"
            },
            {
                "name": "g",
                "children": [
                    {
                        "name": "h"
                    },
                    {
                        "name": "i"
                    }
                ]
            }
        ]
    },
    {
        "name": "j"
    }
]

I have a simple Kotlin function that attempts to iterate on nextToken() as follows:

fun main()
{
    val jsonParser = jacksonObjectMapper().readTree(JSON).traverse()

    while (jsonParser.nextToken() != null)
    {
        val jsonPointer = jsonParser.parsingContext?.pathAsPointer(true) ?: continue
        val tokenName = jsonParser.currentToken.name
        println("${jsonPointer.toString().padEnd(40)} $tokenName")
    }
}

Now, here's what's strange; the jsonPointer isn't distinguishing array indices as indicated in the output:

                                         START_ARRAY
                                         START_OBJECT
/0/name                                  FIELD_NAME
/0/name                                  VALUE_STRING
/0/children                              FIELD_NAME
/0/children                              START_ARRAY
/0/children                              START_OBJECT
/0/children/0/name                       FIELD_NAME
/0/children/0/name                       VALUE_STRING
/0/children                              END_OBJECT
/0/children                              START_OBJECT
/0/children/0/name                       FIELD_NAME
/0/children/0/name                       VALUE_STRING
/0/children                              END_OBJECT
/0/children                              START_OBJECT
/0/children/0/name                       FIELD_NAME
/0/children/0/name                       VALUE_STRING
/0/children                              END_OBJECT
/0/children                              END_ARRAY
                                         END_OBJECT
                                         START_OBJECT
/0/name                                  FIELD_NAME
/0/name                                  VALUE_STRING
/0/children                              FIELD_NAME
/0/children                              START_ARRAY
/0/children                              START_OBJECT
/0/children/0/name                       FIELD_NAME
/0/children/0/name                       VALUE_STRING
/0/children                              END_OBJECT
/0/children                              START_OBJECT
/0/children/0/name                       FIELD_NAME
/0/children/0/name                       VALUE_STRING
/0/children/0/children                   FIELD_NAME
/0/children/0/children                   START_ARRAY
/0/children/0/children                   START_OBJECT
/0/children/0/children/0/name            FIELD_NAME
/0/children/0/children/0/name            VALUE_STRING
/0/children/0/children                   END_OBJECT
/0/children/0/children                   START_OBJECT
/0/children/0/children/0/name            FIELD_NAME
/0/children/0/children/0/name            VALUE_STRING
/0/children/0/children                   END_OBJECT
/0/children/0/children                   END_ARRAY
/0/children                              END_OBJECT
/0/children                              END_ARRAY
                                         END_OBJECT
                                         START_OBJECT
/0/name                                  FIELD_NAME
/0/name                                  VALUE_STRING
                                         END_OBJECT

The paths are always giving back an index of 0, whether in the first or n-th element.

Is this a bug? Or have I somehow managed to introduce one?

Dan Lugg
  • 20,192
  • 19
  • 110
  • 174
  • 2
    I don't know the answer for your question. But it was a bit difficult to understand the code. I think it is better to extract the lambda to a new function and use a simple if (jsonPointer != null) block or something like jsonPointer?let {} instead of when. I – Diego Marin Santos Oct 30 '19 at 20:40
  • Fair enough, I'll fold it down to something simpler. – Dan Lugg Oct 30 '19 at 20:56

1 Answers1

1

It is possible you are experiencing this issue:

https://github.com/FasterXML/jackson-databind/issues/2525

which specifically affects case of "reading" contents of a JsonNode. Handling is fixed for 2.11 (to be released by end of 2019 or early 2020), although not patched for 2.10 yet.

StaxMan
  • 113,358
  • 34
  • 211
  • 239
  • Awesome find, thank you — where can I find snapshot releases for the FasterXML packages? (I’m still relatively new to the Java scene) – Dan Lugg Nov 08 '19 at 14:15
  • 1
    Sonatype OSS repo, `pom.xml` for Jackson packages includes it: `https://oss.sonatype.org/content/repositories/snapshots` – StaxMan Nov 09 '19 at 18:07
  • Thank you! I’ll create an isolated case and report back :-) – Dan Lugg Nov 10 '19 at 02:33