Open
Description
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();