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

Strange NumberFormatException when having maps with Long keys #69

Closed
MrTetrixx opened this issue Apr 3, 2018 · 10 comments
Closed

Strange NumberFormatException when having maps with Long keys #69

MrTetrixx opened this issue Apr 3, 2018 · 10 comments

Comments

@MrTetrixx
Copy link

Hello, I am using zjsonpatch in a project and I really like it.

I ran some of our data through it and came across a strange error. I have not looked at the zjsonpatch code yet but from the stacktrace it looks like it is doing Integer.parseInt() on that Long value used as a key in the map.

The stacktrace:

Exception in thread "main" java.lang.NumberFormatException: For input string: "2407321151"
	at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
	at java.base/java.lang.Integer.parseInt(Integer.java:652)
	at java.base/java.lang.Integer.parseInt(Integer.java:770)
	at com.flipkart.zjsonpatch.JsonDiff.isAllowed(JsonDiff.java:104)
	at com.flipkart.zjsonpatch.JsonDiff.introduceCopyOperation(JsonDiff.java:76)
	at com.flipkart.zjsonpatch.JsonDiff.asJson(JsonDiff.java:60)
	at com.flipkart.zjsonpatch.JsonDiff.asJson(JsonDiff.java:38)
	at JsonDiffTest.main(JsonDiffTest.java:33)

Code to replicate the issue:

public class JsonDiffTest {
    public static void main(String[] args) throws IOException {
        String a = "{\n" +
                "    \"map\": {\n" +
                "      \"3000000000\": {\n" +
                "        \"field\": 3100000000,\n" +
                "        \"otherField\": 0\n" +
                "      }\n" +
                "    }\n" +
                "  }";

        String b = "{\n" +
                "    \"map\": {\n" +
                "      \"3000000000\": {\n" +
                "        \"field\": 3100000000,\n" +
                "        \"otherField\": 0,\n" +
                "        \"extraField\": 0\n" +
                "      }\n" +
                "    }\n" +
                "  }";

        ObjectMapper mapper = new ObjectMapper();
        JsonNode jsonA = mapper.readTree(a);
        JsonNode jsonB = mapper.readTree(b);

        JsonDiff.asJson(jsonA, jsonB); // causes above stacktrace
    }
}

What makes it strange is that

  • if you remove either of otherField or extraField it works.
  • if you change the value of either of the fields with value 0 to anything else it works too.
@vishwakarma
Copy link
Member

Thanks for raising the issue, please allow me a day to look into the issue, I will get back on it very very soon.

@vishwakarma
Copy link
Member

@MrTetrixx This clearly a bug, line #104 & # 105, should be replaced by Long parsing ( this way it wont lose the necessary precision ).
Would you like to raise a PR for same or shall I take over on it?

@MrTetrixx
Copy link
Author

MrTetrixx commented Apr 3, 2018

You can take over, no problem.

Please check if there are any other issues of using unusual keys in a map, like BigDecimal or something.

I extended the test with a real assertion:

        String a = "{" +
                "    \"map\": {" +
                "      \"3000000000\": {" +
                "        \"field\": 3100000000," +
                "        \"otherField\": 0" +
                "      }" +
                "    }" +
                "  }";

        String b = "{" +
                "    \"map\": {" +
                "      \"3000000000\": {" +
                "        \"field\": 3100000000," +
                "        \"otherField\": 0," +
                "        \"extraField\": 0" +
                "      }" +
                "    }" +
                "  }";

        JsonNode jsonA = objectMapper.readTree(a);
        JsonNode jsonB = objectMapper.readTree(b);

        JsonNode diff = JsonDiff.asJson(jsonA, jsonB);

        assertEquals(Operation.ADD.rfcName(), diff.get(0).get("op").textValue());
        assertEquals("/map/3000000000/extraField", diff.get(0).get("path").textValue());
        assertEquals("value", diff.get(0).get("value").textValue());

Should this test return a copy or an add operation? How does it decide between them?

@LouizFC
Copy link
Collaborator

LouizFC commented Apr 5, 2018

@MrTetrixx copy comes over add when you create a field that has a value that is already present on your json.

In your case, you are creating a field called "extraField" with the same value as "otherField", so the copy takes "priority".

The library basically only generates Add and Remove operations if I am not wrong, then these operations are compacted into replace, move and copy operations. You can control this behavior using Flags

@MrTetrixx
Copy link
Author

Yes, I guess I can set the OMIT_COPY_OPERATION and OMIT_MOVE_OPERATION flags to only get add, remove and replace.

@vishwakarma
Copy link
Member

@MrTetrixx , i have put the fix in #70 , would you like to test it?

@MrTetrixx
Copy link
Author

I have run our data through the diff again and it looks much better.
When will the fix be released?

@vishwakarma
Copy link
Member

vishwakarma commented Apr 10, 2018 via email

@MrTetrixx
Copy link
Author

Great, looking forward to it!
(also stop checking github and enjoy your vacation 🍹)

@vishwakarma
Copy link
Member

released 0.4.4, please use it.
Thank you for raising the bug

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

3 participants