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

JsonOps.convertTo explodes on JsonNulls #62

Open
quat1024 opened this issue Apr 11, 2022 · 1 comment
Open

JsonOps.convertTo explodes on JsonNulls #62

quat1024 opened this issue Apr 11, 2022 · 1 comment

Comments

@quat1024
Copy link

quat1024 commented Apr 11, 2022

public static void main(String[] args) {
	JsonObject j = new JsonObject();
	j.add("test", JsonNull.INSTANCE);
	
	System.out.println(JsonOps.INSTANCE.convertTo(JsonOps.INSTANCE, j)); //should return a copy of `j`
}

fails with

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "com.google.gson.JsonElement.getAsJsonPrimitive()" because "input" is null
	at com.mojang.serialization.JsonOps.convertTo(JsonOps.java:50)
	at com.mojang.serialization.JsonOps.convertTo(JsonOps.java:24)
	at com.mojang.serialization.DynamicOps.lambda$convertMap$27(DynamicOps.java:255)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)
	at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1845)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596)
	at com.mojang.serialization.JsonOps.createMap(JsonOps.java:275)
	at com.mojang.serialization.JsonOps.createMap(JsonOps.java:24)
	at com.mojang.serialization.DynamicOps.convertMap(DynamicOps.java:254)
	at com.mojang.serialization.JsonOps.convertTo(JsonOps.java:42)
	at agency.highlysuspect.apathy.rule.CodecUtil.main(CodecUtil.java:145)

It appears there is a check for instanceof JsonNulls:

if (input instanceof JsonNull) {
return outOps.empty();
}
final JsonPrimitive primitive = input.getAsJsonPrimitive();

But it doesn't work, because DynamicOps#getJsonValues, as well as other methods like getStream and getList, filter JsonNulls to actual nulls.

return DataResult.success(input.getAsJsonObject().entrySet().stream().map(entry -> Pair.of(new JsonPrimitive(entry.getKey()), entry.getValue() instanceof JsonNull ? null : entry.getValue())));

@quat1024
Copy link
Author

quat1024 commented Apr 11, 2022

The workaround i'm using in my current project (making a Codec out of something that has toJson and fromJson methods, where toJson sometimes returns JsonObjects containing JsonNulls) is just preprocessing the entire JsonObject and filtering out nulls in objects/arrays, which isn't strictly correct because it loses the distinction between "key present with null value" and "absent key", but in practice it tends to work for what im using it for

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

No branches or pull requests

1 participant