eiiches / jackson-jq Goto Github PK
View Code? Open in Web Editor NEWjq for Jackson Java JSON Processor
License: Other
jq for Jackson Java JSON Processor
License: Other
I'm trying to use this library in an OSGi application, there are a couple of parts that don't seem to work correctly at first glance.
Generally in OSGi using the current thread's context class loader does not work, the OSGi (and general multi-threaded compatible) way is to use the current class's class loader.
net.thisptr.jackson.jq.Scope#loadConfig()
The context class loader cannot load the resolved "jq.json" path.
private static List<JqJson> loadConfig() throws IOException {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
if (loader == null)
loader = Scope.class.getClassLoader();
return loadConfig(loader, resolvePath(Scope.class, "jq.json"));
}
This class's class loader can (and always will be able to):
private static List<JqJson> loadConfig() throws IOException {
return loadConfig(Scope.class.getClassLoader(), resolvePath(Scope.class, "jq.json"));
}
As an aside, using this class's class loader also removes the need for net.thisptr.jackson.jq.Scope#resolvePath
.
net.thisptr.jackson.jq.Scope#loadBuiltinFunctions
The call to ServiceLoader.load(Function.class)
does not find any net.thisptr.jackson.jq.Function
instances.
for (final Function fn : ServiceLoader.load(Function.class)) {
The documentation for ServiceLoader.load(Function.class)
states:
Creates a new service loader for the given service type, using the current thread's context class loader.
Explicitly specifying this class's class loader resolves this issue.
for (final Function fn : ServiceLoader.load(Function.class, this.getClass().getClassLoader())) {
jq prints 1.7976931348623157e+308
for infinite and null for NaN
% jq -n 'infinite, infinite/infinite'
1.7976931348623157e+308
null
% java -jar jackson-jq-cli-1.0.0-preview.20191208.jar -n -- 'infinite, infinite/infinite'
"Infinity"
"NaN"
Thanks for the great library. This is exactly what I was looking for.
Would you consider uploading jackson-jq to Maven Central repo?
Thank you!
I found a case where jackson-jq
returns a different result from jq
:
With jq
(jq-1.6):
$ jq -cn '{key1: true, key2: false} | map_values(select(.))'
{"key1":true}
With jackson-jq
(0.0.10) I get:
{"key1":true,"key2":null}
So key2
is not removed. Perhaps it has something to do with the |=
operator, but the footnote in the readme mentions only throwing errors.
final JsonQuery compile = JsonQuery.compile("...");
q.apply(jsonNode); <- deprecated
Scope scope = new Scope(); <- deprecated
Object pattern allows to specify variable only when it is same as the key.
% echo '{"x": 1}' | jq '. as {$x} | $x'
1
% echo '{"x": 1}' | java -jar jackson-jq-cli-1.0.0-preview.20191208.jar '. as {$x} | $x'
Exception in thread "main" net.thisptr.jackson.jq.exception.JsonQueryException: Cannot compile query: . as {$x} | $x
at net.thisptr.jackson.jq.internal.javacc.ExpressionParser.compile(ExpressionParser.java:34)
at net.thisptr.jackson.jq.JsonQuery.compile(JsonQuery.java:21)
at net.thisptr.jackson.jq.cli.Main.main(Main.java:96)
Caused by: net.thisptr.jackson.jq.internal.javacc.ParseException: Encountered " "$" "$ "" at line 1, column 7.
Was expecting one of:
"and" ...
"or" ...
"(" ...
"@" ...
"true" ...
"false" ...
"null" ...
"\"" ...
"if" ...
"then" ...
"elif" ...
"else" ...
"end" ...
"as" ...
"def" ...
"reduce" ...
"foreach" ...
"try" ...
"catch" ...
"label" ...
"break" ...
"import" ...
"include" ...
"module" ...
<IDENTIFIER> ...
at net.thisptr.jackson.jq.internal.javacc.ExpressionParser.generateParseException(ExpressionParser.java:2380)
at net.thisptr.jackson.jq.internal.javacc.ExpressionParser.jj_consume_token(ExpressionParser.java:2245)
at net.thisptr.jackson.jq.internal.javacc.ExpressionParser.ObjectFieldName(ExpressionParser.java:1090)
at net.thisptr.jackson.jq.internal.javacc.ExpressionParser.ObjectMatcher(ExpressionParser.java:1671)
at net.thisptr.jackson.jq.internal.javacc.ExpressionParser.Matcher(ExpressionParser.java:1630)
at net.thisptr.jackson.jq.internal.javacc.ExpressionParser.PipeComponent(ExpressionParser.java:285)
at net.thisptr.jackson.jq.internal.javacc.ExpressionParser.Expression(ExpressionParser.java:187)
at net.thisptr.jackson.jq.internal.javacc.ExpressionParser.Start(ExpressionParser.java:179)
at net.thisptr.jackson.jq.internal.javacc.ExpressionParser.compile(ExpressionParser.java:30)
... 2 more
I accidentally stumbled upon another incompatibility with jq (jq-1.6):
$ jq -n '"\/"'
"/"
with jackson-jq (0.0.11):
...
Caused by: java.lang.IllegalStateException: Unexpected escape char: /
at net.thisptr.jackson.jq.internal.javacc.JsonQueryParser.StringInterpolation(JsonQueryParser.java:1428)
at net.thisptr.jackson.jq.internal.javacc.JsonQueryParser.PrimaryExpression(JsonQueryParser.java:512)
at net.thisptr.jackson.jq.internal.javacc.JsonQueryParser.BinaryOperatorExpression(JsonQueryParser.java:271)
at net.thisptr.jackson.jq.internal.javacc.JsonQueryParser.TupleExpression(JsonQueryParser.java:244)
at net.thisptr.jackson.jq.internal.javacc.JsonQueryParser.JsonQuery(JsonQueryParser.java:171)
at net.thisptr.jackson.jq.internal.javacc.JsonQueryParser.Start(JsonQueryParser.java:162)
at net.thisptr.jackson.jq.internal.javacc.JsonQueryParser.compile(JsonQueryParser.java:23)
at net.thisptr.jackson.jq.JsonQuery.compile(JsonQuery.java:38)
... 3 more
It seems that jq allows escaping forward slashes, and JSON does too (https://stackoverflow.com/questions/1580647/json-why-are-forward-slashes-escaped). Perhaps it was carried over from JavaScript, where escaping /
might be required when you want to write a regex like /\//
...
The .del function is missing. .del removes a key and its corresponding value from an object.
https://stedolan.github.io/jq/manual/#example20
Any plans to add it?
I discovered a difference between jq
and jq-jackson
, shown via this simple example:
$ echo '{"foo":[2]}' | jq -c '.foo[]? |= . + 2'
{"foo":[4]}
$ echo '{"foo":null}' | jq -c '.foo[]? |= . + 2'
{"foo":null}
The first example works with jackson-jq, the second throws:
JsonQueryException Cannot iterate over null net.thisptr.jackson.jq.internal.misc.JsonNodeUtils.mutate (JsonNodeUtils.java:237)
The README lists "to_entries, from_entries, with_entries" on the implemented features list. When I try to use with_entries, I get the exception "net.thisptr.jackson.jq.exception.JsonQueryException: Function with_entries/1 does not exist". Also, there is no WithEntriesFunction.java in https://github.com/eiiches/jackson-jq/tree/develop/jackson-jq/src/main/java/net/thisptr/jackson/jq/internal/functions.
I assume that this is just an oversight, since according to the jq documentation, with_entries is just "with_entries(foo) is a shorthand for to_entries | map(foo) | from_entries"
The extra bundle net.thisptr.jackson-jq-extra imports the packages net.thisptr.jackson.jq.internal.misc and net.thisptr.jackson.jq.internal but they are not exported by the main bundle net.thisptr.jackson-jq. It cannot be used/installed in an OSGi environment.
Please see:
https://stedolan.github.io/jq/manual/#walk(f)
From builtin.jq:
# Apply f to composite entities recursively, and to atoms
def walk(f):
. as $in
| if type == "object" then
reduce keys[] as $key
( {}; . + { ($key): ($in[$key] | walk(f)) } ) | f
elif type == "array" then map( walk(f) ) | f
else f
end;
I want to call a JVM method to query a JsonNode instead of shelling out to jq
. I don't want to run the CLI because that would defeat the purpose of using a JVM library. I just want to do simple things, like the programmatic equivalent of the following:
jq -r ".propertyName"
jq -r ".roots[] | select(.name == \"production\")"
Surely this must be trivial to do, but I don't see how. I'd love to understand how to use this library. Perhaps a "Jackson-JQ For Dummies" section might be helpful, with simple examples like the above.
Also, I don't get what Scope
is for. Is that explained somewhere? What scope(s) would I need for the above?
Thanks,
Mike
Hi,
I'm trying to integrate jackson-jq 0.0.12 with RapidMiner using Groovy scripting.
(Branch 1.x is marked with unstable API, should I rather use that?)
The script is more or less identical to Main.java in jackson-jq-cli. It works well, converting JSON to JSON. However, I get an exception when trying to convert to CSV:
The scripting engine Groovy reported an error in the script: net.thisptr.jackson.jq.exception.JsonQueryException: Formatting operator @csv does not exist.
Caused by: net.thisptr.jackson.jq.exception.JsonQueryException: Formatting operator @csv does not exist
at net.thisptr.jackson.jq.internal.tree.FormattingFilter.apply(FormattingFilter.java:24)
at net.thisptr.jackson.jq.internal.tree.PipedQuery.applyRecursive(PipedQuery.java:42)
at net.thisptr.jackson.jq.internal.tree.PipedQuery.applyRecursive(PipedQuery.java:55)
at net.thisptr.jackson.jq.internal.tree.PipedQuery.applyRecursive(PipedQuery.java:55)
at net.thisptr.jackson.jq.internal.tree.PipedQuery.applyRecursive(PipedQuery.java:55)
at net.thisptr.jackson.jq.internal.tree.PipedQuery.applyRecursive(PipedQuery.java:55)
at net.thisptr.jackson.jq.internal.tree.PipedQuery.apply(PipedQuery.java:25)
at net.thisptr.jackson.jq.internal.IsolatedScopeQuery.apply(IsolatedScopeQuery.java:21)
at net.thisptr.jackson.jq.JsonQuery.apply(JsonQuery.java:21)
at net.thisptr.jackson.jq.JsonQuery$apply$0.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
Do you have an idea if this is supposed to work, and how?
Thanks for creating jackson-jq!
The following jq queries all fail with the same error:
.actor."spt:userId" )
.actor )
)
The stack trace is
java.util.EmptyStackException
at java.util.Stack.peek(Stack.java:102)
at java.util.Stack.pop(Stack.java:84)
at net.thisptr.jackson.jq.internal.javacc.JsonQueryParserTokenManager.TokenLexicalActions(JsonQueryParserTokenManager.java:1025)
at net.thisptr.jackson.jq.internal.javacc.JsonQueryParserTokenManager.getNextToken(JsonQueryParserTokenManager.java:965)
at net.thisptr.jackson.jq.internal.javacc.JsonQueryParser.jj_ntk_f(JsonQueryParser.java:2172)
at net.thisptr.jackson.jq.internal.javacc.JsonQueryParser.PrimaryExpression(JsonQueryParser.java:424)
at net.thisptr.jackson.jq.internal.javacc.JsonQueryParser.BinaryOperatorExpression(JsonQueryParser.java:226)
at net.thisptr.jackson.jq.internal.javacc.JsonQueryParser.TupleExpression(JsonQueryParser.java:199)
at net.thisptr.jackson.jq.internal.javacc.JsonQueryParser.JsonQuery(JsonQueryParser.java:126)
at net.thisptr.jackson.jq.internal.javacc.JsonQueryParser.Start(JsonQueryParser.java:117)
at net.thisptr.jackson.jq.internal.javacc.JsonQueryParser.compile(JsonQueryParser.java:22)
at net.thisptr.jackson.jq.JsonQuery.compile(JsonQuery.java:36)
jq has semantics for indexing array with array (get the indices) but jackson-jq does not implement this.
% echo '[1,2,3,2,1,2,3]' | jq '.[[2]]'
[
1,
3,
5
]
% echo '[1,2,3,2,1,2,3]' | java -jar jackson-jq-cli-1.0.0-preview.20191208.jar '.[[2]]'
jq: error: Cannot index array with array
Fails:
jsonQuery = JsonQuery.compile(".userId as $uid | {$uid}");
Succeeds:
jsonQuery = JsonQuery.compile(".userId as $uid | {\"userId\": $uid}");
jsonQuery = JsonQuery.compile(".userId as $uid | {userId}");
I believe the first should perform the same as either of the others which succeed (except with a different name, "uid" in its case) per https://jqplay.org/s/pfvuR4JLfc
Is this something I've missed from the list of missing features or a bug? Obviously, the first successful query I've mentioned is an acceptable workaround, just a tad unnecessarily verbose.
jq has a function scope in parenthesis but jackson-jq does not handle this
% jq -n 'def f: 1; . | (def f: 2; f) | f, .'
1
2
% java -jar jackson-jq-cli-1.0.0-preview.20191208.jar -n 'def f: 1; . | (def f: 2; f) | f, .'
2
2
Edit: arrays and objects have function scope too
'def f: 1; . | [def f: 2; f] | f, .'
'def f: 1; . | {(def f: "foo"; f): f}'
Hello guys, we are in the process of migrating to JDK11 and your library is not compatible with JDK11 because of transient dependency: org.jruby.joni:joni:2.1.11.
I talked the them to release a compatible version which they recently did jruby/joni#42. Could you please release a new JDK11 compatible version?
Thank you.
Hey, I think I found another inconsistency with original jq. I'm using 0.0.11, perhaps it works correctly in the 1.0.0 preview (I haven't checked that).
jq 1.6:
$ jq -n '"test" | .[1:null]'
"est"
jackson-jq 0.0.11:
Exception in thread "main" net.thisptr.jackson.jq.exception.JsonQueryException: Start and end indices of an string slice must be numbers
at net.thisptr.jackson.jq.exception.JsonQueryException.format(JsonQueryException.java:35)
at net.thisptr.jackson.jq.internal.tree.fieldaccess.BracketFieldAccess.resolveFieldAccess(BracketFieldAccess.java:62)
at net.thisptr.jackson.jq.internal.tree.fieldaccess.FieldAccess.apply(FieldAccess.java:40)
at net.thisptr.jackson.jq.internal.tree.PipedQuery.applyRecursive(PipedQuery.java:42)
at net.thisptr.jackson.jq.internal.tree.PipedQuery.applyRecursive(PipedQuery.java:55)
at net.thisptr.jackson.jq.internal.tree.PipedQuery.apply(PipedQuery.java:25)
at net.thisptr.jackson.jq.internal.IsolatedScopeQuery.apply(IsolatedScopeQuery.java:21)
...
jq -s '.[0] * {"channel_group":{"groups":{"Application":{"groups": {"Org3MSP":.[1]}}}}}' config.json org3.json > modified_config.json
config.json: {"channel_group":{"groups":{"Application":{"groups": {"Org1MSP":"org1"}}}}}
org3.json:{"sex":"man"}"
how to use jackson-jq to impliment it?
Have you considered publishing a homebrew recipe for this?
http://formalfriday.club/2015/01/05/creating-your-own-homebrew-tap-and-formula.html
Once you have a bundle, it's pretty straightforward e.g.
https://github.com/yschimke/homebrew-tap/blob/okcurl/okcurl.rb
The following code snippet:
val input = DEFAULT.createObjectNode();
input.put("x", 1);
val expression = "(.. | numbers) += 1";
val query = JsonQuery.compile(expression);
val result = query.apply(input).get(0);
fails with:
net.thisptr.jackson.jq.exception.IllegalJsonArgumentException: left hand side must be FieldAccess
at net.thisptr.jackson.jq.internal.tree.binaryop.assignment.ComplexAssignment.apply(ComplexAssignment.java:31)
at net.thisptr.jackson.jq.internal.IsolatedScopeQuery.apply(IsolatedScopeQuery.java:21)
at net.thisptr.jackson.jq.JsonQuery.apply(JsonQuery.java:20)
Please see http://stackoverflow.com/questions/35609548/how-to-apply-a-function-to-all-strings-in-records-structure-recursively-using-j for context.
In general, preference should be given to the context classloader. This can be done as follows:
public static URL getResource(String resourceName) {
ClassLoader loader = Objects.firstNonNull(
Thread.currentThread().getContextClassLoader(),
Resources.class.getClassLoader());
URL url = loader.getResource(resourceName);
checkArgument(url != null, "resource %s not found.", resourceName);
return url;
}
This should be done here:
Otherwise things will break in certain environments (e.g. JEE, Spring Boot, etc.)
I want to write a value to an inner object. Here is the jq/bash code, which works:
X="$( jq '(.profiles[] | select(.name=="Ubuntu") | .cursorShape)="vintage"' "$WTJ" )" && echo "$X" > "$WTJ"
This is some Scala code that is supposed to mirror the above jq/bash code:
import com.fasterxml.jackson.databind.{JsonNode, ObjectMapper}
val file = new java.io.File("/mnt/c/Users/mslinn/AppData/Local/Packages/Microsoft.WindowsTerminal_8wekyb3d8bbwe/RoamingState/profiles.json")
val json: JsonNode = new ObjectMapper().readTree(file)
val cursorShape = "vintage"
val query = s""".profiles[] | select(.name=="Ubuntu") | .cursorShape)="$cursorShape""""
val newJson: Seq[JsonNode] = jq(json, query)
When the program runs, and tries to compile the query, I get the error java.lang.IllegalStateException: Unexpected ')' at line 1, column 53.
. Is there another way to update an object within an array of objects?
First of all, thanks for this great library, I found it really useful!
I stumbled upon a difference in the implementation of to_entries
. While jq manual does not seem to mention it, to_entries
can be used on arrays, like this:
$ jq --version
jq-1.6
$ jq -n '["a", "b", "c"] | to_entries'
[
{
"key": 0,
"value": "a"
},
{
"key": 1,
"value": "b"
},
{
"key": 2,
"value": "c"
}
]
jackson-jq only accepts objects as input to to_entries
.
I know this is kind of a weird edge-case, but thought I'd document it anyway:
$ echo '{"foreach":42}' | jq -c '.foreach'
42
Throws exception in jackson-jq:
ParseException Encountered " "foreach" "foreach "" at line 1, column 2.
Was expecting one of:
<EOF>
"
...
I have a very simple JQ filter like this:
.scores|length
And then I have a simple JSON like this:
{ "scores": [ 0, 1, 2, 3 ] }
When I to apply the query, I get an exception though, with this message:
Function length/0 does not exist
Stack trace:
Caused by: net.thisptr.jackson.jq.exception.JsonQueryException: Function length/0 does not exist
at net.thisptr.jackson.jq.internal.tree.FunctionCall.apply(FunctionCall.java:30)
at net.thisptr.jackson.jq.internal.tree.PipedQuery.pathRecursive(PipedQuery.java:52)
at net.thisptr.jackson.jq.internal.tree.PipedQuery.lambda$pathRecursive$2(PipedQuery.java:53)
at net.thisptr.jackson.jq.path.ObjectFieldPath.resolve(ObjectFieldPath.java:83)
at net.thisptr.jackson.jq.internal.tree.fieldaccess.FieldAccess.emitObjectFieldPath(FieldAccess.java:55)
at net.thisptr.jackson.jq.internal.tree.fieldaccess.IdentifierFieldAccess.lambda$apply$0(IdentifierFieldAccess.java:35)
at net.thisptr.jackson.jq.internal.tree.ThisObject.apply(ThisObject.java:20)
at net.thisptr.jackson.jq.internal.tree.fieldaccess.IdentifierFieldAccess.apply(IdentifierFieldAccess.java:34)
at net.thisptr.jackson.jq.internal.tree.PipedQuery.pathRecursive(PipedQuery.java:52)
at net.thisptr.jackson.jq.internal.tree.PipedQuery.apply(PipedQuery.java:25)
at net.thisptr.jackson.jq.internal.IsolatedScopeQuery.apply(IsolatedScopeQuery.java:21)
at net.thisptr.jackson.jq.Expression.apply(Expression.java:11)
at net.thisptr.jackson.jq.JsonQuery.apply(JsonQuery.java:17)
I'm using a Maven project, with these dependencies defined:
<dependency>
<groupId>net.thisptr</groupId>
<artifactId>jackson-jq</artifactId>
<version>1.0.0-preview.20190925</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.10</version>
</dependency>
Any hints would be appreciated.
When contains/1
is given a non-string value, jackson-jq returns false
, whereas jq exits with an error. This should be fixed.
$ jackson-jq 'contains("str")' <<< true
false
$ jq 'contains("str")' <<< true
jq: error (at <stdin>:1): boolean (true) and string ("str") cannot have their containment checked
when I was trying to make a build of it, and the error happened.
Thanks
There's inconsistency with jq for the following case.
% echo '{"x": ["a", "b"], "y": [{"a": 1, "b": 3}, {"a": 2, "b": 4}] }' | jq '.y[][.x[]]'
1
2
3
4
% echo '{"x": ["a", "b"], "y": [{"a": 1, "b": 3}, {"a": 2, "b": 4}] }' | java -jar jackson-jq-cli-1.0.0-preview.20191208.jar '.y[][.x[]]'
1
3
2
4
I'm using jq-1.5 (the executable version written in C), and am amazed how much REST API programming I can do in bash simply using curl and jq.
But now we are creating complex JSON objects that don't do well when being parsed by a spring boot app. Its not really feasible to convert JSON objects to Java Value Objects. We want the Value Objects to be populated fetching attributes values from a JSON file using JQ rather than force the creation of a complex Java object just so that it can be streamed to and from our "Business Object" represented in JSON with embedded objects and such. We also want to be able to account for additional attributes that are added dynamically to the JSON data structure without breaking the code.
Will this library make it just as easy to pull attributes out of complex JSON structures, or transform JSON structures as it with JQ in a bash shell script?
Trowing exception as Cannot index string with string "entityList". If we execute in [https://jqplay.org/] returning proper response.
`String response = "";
String json = "{"page":"1","totalRecords":"27","totalPages":"1","status":"success","entityList":[{"ENAME":"KING","DNAME":"ACCOUNTING","JOB":"PRESIDENT","EMPNO":"7839","HIREDATE":"1981-11-17 00:00:00.0","LOC":"NEW YORK"},{"ENAME":"BLAKE","DNAME":"SALES","JOB":"MANAGER","EMPNO":"7698","HIREDATE":"1981-05-01 00:00:00.0","LOC":"CHICAGO"},{"ENAME":"CLARK","DNAME":"ACCOUNTING","JOB":"MANAGER","EMPNO":"7782","HIREDATE":"1981-06-09 00:00:00.0","LOC":"NEW YORK"},{"ENAME":"JONES","DNAME":"RESEARCH","JOB":"MANAGER","EMPNO":"7566","HIREDATE":"1981-04-02 00:00:00.0","LOC":"DALLAS"},{"ENAME":"SCOTT","DNAME":"RESEARCH","JOB":"ANALYST","EMPNO":"7788","HIREDATE":"1987-04-19 00:00:00.0","LOC":"DALLAS"}]}";
String filter = "{"entityList":[.entityList[] |select((.ENAME=="KING"))],"totalRecords":.totalRecords,"totalPages":.totalPages,"page":.page,"status":.status}";
try {
filter = filter.replaceAll("\\", "");
ObjectMapper MAPPER = new ObjectMapper();
JsonNode in = MAPPER.valueToTree(json);
JsonQuery q = JsonQuery.compile(filter);
List result = q.apply(in);
response = result.toString();
System.out.println("filtered response "+response);
} catch (Exception e) {
e.printStackTrace();
}`
When I used the following query : ". | {name | .name , age | .age} the resulting nodes keys are sorted so it will return {age : "", name : ""}.
This is one of the most useful features of jq
$ oksocial https://api.twitter.com/1.1/statuses/user_timeline.json | jq . | head -3
[
{
"created_at": "Sun Apr 10 06:13:19 +0000 2016",
$ oksocial https://api.twitter.com/1.1/statuses/user_timeline.json | java -jar ~/Downloads/jackson-jq-cli-0.0.4.jar .
[{"created_at":"Sun Apr 10 06:13:19 +0000 2016","id":719045577518899200,"id_str":"719045577518899200"...
jackson-jq seems to have bug around indices/1 when the argument is an empty string.
% jq -n '"x" | indices("")'
[]
% java -jar jackson-jq-cli-1.0.0-preview.20191208.jar -n '"x" | indices("")'
I have encountered a case (I'd think a pretty common one) where I cannot catch an exception with the try-catch expression:
jq:
$ jq -n '[82, "WAT", 22] | map(try tonumber)'
[
82,
22
]
jackson-jq:
Exception in thread "main" java.lang.NumberFormatException: For input string: "WAT"
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2043)
at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
at java.lang.Double.parseDouble(Double.java:538)
at net.thisptr.jackson.jq.internal.functions.ToNumberFunction.apply(ToNumberFunction.java:22)
at net.thisptr.jackson.jq.internal.tree.FunctionCall.apply(FunctionCall.java:26)
at net.thisptr.jackson.jq.internal.tree.TryCatch.apply(TryCatch.java:29)
at net.thisptr.jackson.jq.internal.FixedScopeQuery.apply(FixedScopeQuery.java:22)
at net.thisptr.jackson.jq.internal.JsonQueryFunction.applyRecursive(JsonQueryFunction.java:42)
at net.thisptr.jackson.jq.internal.JsonQueryFunction.apply(JsonQueryFunction.java:36)
at net.thisptr.jackson.jq.internal.tree.FunctionCall.apply(FunctionCall.java:26)
at net.thisptr.jackson.jq.internal.tree.PipedQuery.applyRecursive(PipedQuery.java:42)
at net.thisptr.jackson.jq.internal.tree.PipedQuery.applyRecursive(PipedQuery.java:55)
at net.thisptr.jackson.jq.internal.tree.PipedQuery.apply(PipedQuery.java:25)
at net.thisptr.jackson.jq.internal.tree.ArrayConstruction.apply(ArrayConstruction.java:29)
at net.thisptr.jackson.jq.internal.IsolatedScopeQuery.apply(IsolatedScopeQuery.java:21)
at net.thisptr.jackson.jq.internal.JsonQueryFunction.applyRecursive(JsonQueryFunction.java:42)
at net.thisptr.jackson.jq.internal.JsonQueryFunction.applyRecursive(JsonQueryFunction.java:53)
at net.thisptr.jackson.jq.internal.JsonQueryFunction.apply(JsonQueryFunction.java:36)
at net.thisptr.jackson.jq.internal.tree.FunctionCall.apply(FunctionCall.java:26)
at net.thisptr.jackson.jq.internal.tree.PipedQuery.applyRecursive(PipedQuery.java:42)
at net.thisptr.jackson.jq.internal.tree.PipedQuery.applyRecursive(PipedQuery.java:55)
at net.thisptr.jackson.jq.internal.tree.PipedQuery.apply(PipedQuery.java:25)
at net.thisptr.jackson.jq.internal.IsolatedScopeQuery.apply(IsolatedScopeQuery.java:21)
...
Seems that TryCatch
is expecting only a specific type of exceptions:
try {
return tryExpr.apply(scope, in);
} catch (JsonQueryException e) {
...
}
but ToNumberFunction
is throwing simply a NumberFormatException
.
It would be great if you could please release the latest changes to Maven Central. Thanks so much!
For example,
% jq -n -c '[range(5)] | (.[2:0] = [999])'
[0,1,999,2,3,4]
% java -jar jackson-jq-cli-1.0.0-preview.20191208.jar -n -c '[range(5)] | (.[2:0] = [999])'
[999,0,1,2,3,4]
Has anyone tried to compile this with GraalVM's native-image
command? (Does it use reflection or other features that aren't support in native-image
?)
I have a command-line tool, I'm compiling with native-image
and would love to be able to include this as a library to add JsonQuery processing!
This is deprecated:
So far I have used something like this:
JsonQuery query = ...;
ObjectMapper mapper = new ObjectMapper();
JsonNode in = mapper.readTree(someStringContainingAnArray);
List<JsonNode> resultOfQuery = query.apply(in);
What is the recommended substitute for JsonQuery.apply(JsonNode)? What
Scope` should be passed as the first argument to this?
When loading all macros, they are all created without specifying a Scope.
Which is a call to:
... which uses Scope.rootScope()
which is not guaranteed to be the same scope as the query has been compiled with.
My hunch is that Scope.loadMacros
just needs to call new JsonQueryFunction
with this
as the closure scope, though I've yet to prove it or encode it in a unit test.
addFunction(def.name, def.args.size(), new JsonQueryFunction(def.name, def.args, JsonQuery.compile(def.body), this));
$ ... | java -jar ~/Downloads/jackson-jq-cli-0.0.4.jar .sdf
jq: error: Cannot index array with string "sdf"
$ echo $?
0
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.