Skip to content

Predicate testing forces dependency on Minidev json-smart #274

Open
@johnflavin

Description

@johnflavin

When using a Predicate expression to filter a value, a new Configuration is built with no mappingProvider (ValueNode line 808). This forces the ConfigurationBuilder to call getEffectiveDefaults(). If an alternate mappingProvider was set on the context, but not set as a default, this will be ignored and the default minidev JsonReader will be used; if it isn't on the classpath this causes a java.lang.NoClassDefFoundError: net/minidev/json/writer/JsonReaderI exception.

Here's a simple test with a predicate expression:

@Test
public void testJsonPathWPredicate() throws Exception {
    final Configuration configuration = Configuration.builder()
            .jsonProvider(new JacksonJsonProvider())
            .mappingProvider(new JacksonMappingProvider())
            .build();

    final String json = "{\"outerKey1\": {\"innerKey1\": \"value\", \"innerKey2\": \"foo\"}}";
    final String predicateExpr = "$.outerKey1[?(@.innerKey2 == 'foo')].innerKey1";
    final List<String> result = JsonPath.using(configuration).parse(json).read(predicateExpr);
    assertEquals(Lists.newArrayList("value"), result);
}

If you do not have minidev json-smart on your classpath, this test will throw

java.lang.NoClassDefFoundError: net/minidev/json/writer/JsonReaderI

    at com.jayway.jsonpath.internal.DefaultsImpl.<init>(DefaultsImpl.java:17)
    at com.jayway.jsonpath.internal.DefaultsImpl.<clinit>(DefaultsImpl.java:15)
    at com.jayway.jsonpath.Configuration.getEffectiveDefaults(Configuration.java:48)
    at com.jayway.jsonpath.Configuration.access$000(Configuration.java:34)
    at com.jayway.jsonpath.Configuration$ConfigurationBuilder.build(Configuration.java:229)
    at com.jayway.jsonpath.internal.filter.ValueNode$PathNode.evaluate(ValueNode.java:808)
    at com.jayway.jsonpath.internal.filter.RelationalExpressionNode.apply(RelationalExpressionNode.java:37)
    at com.jayway.jsonpath.internal.filter.FilterCompiler$CompiledFilter.apply(FilterCompiler.java:400)
    at com.jayway.jsonpath.internal.path.PredicatePathToken.accept(PredicatePathToken.java:76)
    at com.jayway.jsonpath.internal.path.PredicatePathToken.evaluate(PredicatePathToken.java:46)
    at com.jayway.jsonpath.internal.path.PathToken.handleObjectProperty(PathToken.java:81)
    at com.jayway.jsonpath.internal.path.PropertyPathToken.evaluate(PropertyPathToken.java:79)
    at com.jayway.jsonpath.internal.path.RootPathToken.evaluate(RootPathToken.java:62)
    at com.jayway.jsonpath.internal.path.CompiledPath.evaluate(CompiledPath.java:53)
    at com.jayway.jsonpath.internal.path.CompiledPath.evaluate(CompiledPath.java:61)
    at com.jayway.jsonpath.JsonPath.read(JsonPath.java:187)
    at com.jayway.jsonpath.internal.JsonContext.read(JsonContext.java:164)
    at com.jayway.jsonpath.internal.JsonContext.read(JsonContext.java:151)

I believe this could be fixed by changing ValueNode line 808 to explicitly set the mappingProvider (even if it is never used).

Configuration c = Configuration.builder().jsonProvider(ctx.configuration().jsonProvider()).options(Option.REQUIRE_PROPERTIES).build();

to

Configuration c = Configuration.builder().jsonProvider(ctx.configuration().jsonProvider()).mappingProvider(ctx.configuration().mappingProvider()).options(Option.REQUIRE_PROPERTIES).build();

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions