Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Predicate testing forces dependency on Minidev json-smart #274

Open
johnflavin opened this issue Oct 19, 2016 · 5 comments
Open

Predicate testing forces dependency on Minidev json-smart #274

johnflavin opened this issue Oct 19, 2016 · 5 comments
Labels

Comments

@johnflavin
Copy link

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();
@detyo
Copy link

detyo commented Jan 9, 2017

I also hit this issue when running in OSGi environment. I even considered installing json smart library to work around it, but finally I ended up dropping the predicates and manually checking the elements. I would love to see this fixed.

@jochenberger
Copy link
Contributor

I'd say this is a non-issue. IMO, json-smart is a dependency and if you exclude it from your classpath, things stop working.

@jochenberger
Copy link
Contributor

If we had a way to parse JSON within the query in a provider-independent fashion, we could make the dependency optional again. Of course, we could just copy over the relevant code from the json-smart library, but I wouldn't consider that an optimal solution.
I'm beginning to wonder how much work it would be to port the query parsing to ANTLR...

@johnflavin
Copy link
Author

I don't understand why the fix I proposed in the initial ticket is not appropriate.

I have put a non-default mappingProvider on the Configuration. It is being used everywhere except for predicate checking, where it isn't being used and the default is used instead. But it easily could be used. The fix is simple. Is there some reason that should not be done?

@jochenberger
Copy link
Contributor

See #275. Some providers do not support parsing JSON with single quotes. But since the JsonPath specs allow that, we cannot use the provider.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants