How to resolve spinjar.com.jayway.jsonpath.PathNotFoundException: No results for path: xxx

Reference on GitHub - json-path/JsonPath: Java JsonPath implementation about the ‘PathNotFoundException’ exception solution is to change the default com.jayway.jsonpath.Configuration, such as set Option# DEFAULT_PATH_LEAF_TO_NULL, Option# SUPPRESS_EXCEPTIONS to suppress the following situation caused by abnormal:

{
    "name":{
        "first":"Tatu",
        "last":"Saloranta"
    },
    "title":"Jackson founder",
    "company":"FasterXML",
    "pets":[
        {
            "type":"dog",
            "number":1
        },
        {
            "type":"fish",
            "number":50
        }
    ]
}
@Test
public void testJayJsonPath() {
    // cause com.jayway.jsonpath.PathNotFoundException: No results for path: $['name']['first1']
    try {
        String firstName0 = JsonPath.read(json, "$.name.first1");
    } catch (Exception e) {
        Assert.assertTrue(e instanceof PathNotFoundException);
    }

    // work fine
    ParseContext context1 = JsonPath.using(Configuration.defaultConfiguration().setOptions(Option.DEFAULT_PATH_LEAF_TO_NULL));
    String firstName1 = context1.parse(json).read("$.name.first1");
    Assert.assertEquals(firstName1, null);

    // cause com.jayway.jsonpath.PathNotFoundException: Missing property in path $['user']
    try {
        String firstName2 = context1.parse(json).read("$.user.first1");
    } catch (Exception e) {
        Assert.assertTrue(e instanceof PathNotFoundException);
    }

    // work fine
    ParseContext context2 = JsonPath.using(Configuration.defaultConfiguration().setOptions(Option.SUPPRESS_EXCEPTIONS));
    String firstName3 = context2.parse(json).read("$.name.first1");
    Assert.assertEquals(firstName3, null);

    // global configuration
    init();

    // work fine
    String firstName4 = JsonPath.read(json, "$.name.first1");
    Assert.assertEquals(firstName3, null);

    // work fine
    String firstName5 = JsonPath.read(json, "$.user.first1");
    Assert.assertEquals(firstName3, null);
}

public void init() {
    Configuration.setDefaults(new Configuration.Defaults() {

        private final JsonProvider jsonProvider = new JacksonJsonProvider();
        private final MappingProvider mappingProvider = new JacksonMappingProvider();

        @Override
        public JsonProvider jsonProvider() {
            return jsonProvider;
        }

        @Override
        public MappingProvider mappingProvider() {
            return mappingProvider;
        }

        @Override
        public Set<Option> options() {
            return EnumSet.of(Option.DEFAULT_PATH_LEAF_TO_NULL, Option.SUPPRESS_EXCEPTIONS);
            // return EnumSet.noneOf(Option.class);
        }
    });
}

But i get same exception at below in Camunda Spin plugin env

public void initWithSpin() {
    spinjar.com.jayway.jsonpath.Configuration.setDefaults(new spinjar.com.jayway.jsonpath.Configuration.Defaults() {

        private final spinjar.com.jayway.jsonpath.spi.json.JsonProvider jsonProvider = new spinjar.com.jayway.jsonpath.spi.json.JacksonJsonProvider();
        private final spinjar.com.jayway.jsonpath.spi.mapper.MappingProvider mappingProvider = new spinjar.com.jayway.jsonpath.spi.mapper.JacksonMappingProvider();

        @Override
        public spinjar.com.jayway.jsonpath.spi.json.JsonProvider jsonProvider() {
            return jsonProvider;
        }

        @Override
        public spinjar.com.jayway.jsonpath.spi.mapper.MappingProvider mappingProvider() {
            return mappingProvider;
        }

        @Override
        public Set<spinjar.com.jayway.jsonpath.Option> options() {
            return EnumSet.of(spinjar.com.jayway.jsonpath.Option.DEFAULT_PATH_LEAF_TO_NULL, spinjar.com.jayway.jsonpath.Option.SUPPRESS_EXCEPTIONS);
            // return EnumSet.noneOf(Option.class);
        }
    });
}

@Test
public void testWithSpinJsonPath() {
    initWithSpin();
    JsonValue jsonValue = SpinValues.jsonValue(json).create();
    SpinJsonNode jsonNode = jsonValue.getValue();

    String firstName = jsonNode.jsonPath("$.name.first").stringValue();
    Assert.assertEquals(firstName, "Tatu");

    String firstName1 = jsonNode.jsonPath("$.name.first1").stringValue();
    Assert.assertEquals(firstName, null);
}

I find Camunda document that spin/extending-spin/#custom-dataformats tell me should provide a customer data formatter for spin to parse JSON type, but then I will overwrite a formatter already provided by spin. Is there any other way?

I decided resolve that with a ‘Configuring Data Formats’ spi, like this:

public class DataFormatConfiguratorImpl implements DataFormatConfigurator {

    @Override
    public Class getDataFormatClass() {
        return JacksonJsonDataFormat.class;
    }

    @Override
    public void configure(DataFormat dataFormat) {
        if (dataFormat instanceof JacksonJsonDataFormat) {
            JacksonJsonDataFormat jsonDataFormat = (JacksonJsonDataFormat) dataFormat;
            jsonDataFormat.setJsonPathConfiguration(
                    Configuration.defaultConfiguration().addOptions(Option.DEFAULT_PATH_LEAF_TO_NULL, Option.SUPPRESS_EXCEPTIONS)
            );
        }
    }
}

After that i got expect result!

@Test
public void testWithSpinJsonPath() {
    JsonValue jsonValue = SpinValues.jsonValue(json).create();
    SpinJsonNode jsonNode = jsonValue.getValue();

    // cause exception: org.camunda.spin.json.SpinJsonDataFormatException: SPIN/JACKSON-JSON-01002 Expected 'String', got 'NULL'
    try {
        String firstName0 = jsonNode.jsonPath("$.name.first1").stringValue();
    } catch (Exception e) {
        // nothing ..
    }

    // work fine
    Object firstName1 = jsonNode.jsonPath("$.name.first1").element().value();
    Assert.assertEquals(firstName1, null);

    // work fine
    Object firstName2 = jsonNode.jsonPath("$.user.first1").element().value();
    Assert.assertEquals(firstName2, null);
}

Thank every reader!

1 Like