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

V1Secret equals always returns false #431

Open
davidxia opened this Issue Nov 9, 2018 · 6 comments

Comments

Projects
None yet
2 participants
@davidxia
Contributor

davidxia commented Nov 9, 2018

Two V1Secret instances deserialized from the same YAML are not equal. In fact, V1Secret.equals(Object o) always returns false. This is because V1Secret.data = Map<String, byte[]>.

private Map<String, byte[]> data = null;

The equals method on a Java array type is equivalent to ==. So this line returns false.

Objects.equals(this.data, v1Secret.data) &&

Would you be open to patches for this? If so, what's the right approach? Keep the V1Secret.data = Map<String, byte[]> and modify the line above to loop through the map checking keys are equal with Objects.equals() and byte[] values are equal with java.util.Arrays.equals(...)?

@brendandburns

This comment has been minimized.

Collaborator

brendandburns commented Nov 9, 2018

This is really very unfortunate. That code is generated, so we can't manually patch it. We could override it with our own class (similar to IntToString or Quantity) if we really wanted to.

Alternately, we could update the SwaggerCodegen here:

https://github.com/swagger-api/swagger-codegen/blob/master/modules/swagger-codegen/src/main/resources/Java/pojo.mustache#L164

To be smarter...

@davidxia

This comment has been minimized.

Contributor

davidxia commented Nov 9, 2018

@brendanburns thanks for explaining. Any preference of approach? I can try to make a PR for the first approach if it'll help.

@davidxia

This comment has been minimized.

Contributor

davidxia commented Nov 11, 2018

@brendanburns Ah I see what you meant by linking to SwaggerCodegen. Looks like that line to handle byte arrays was fixed by this PR. Does this mean the version of SwaggerCodegen used by this repo is outdated and should be upgraded? Maybe an upgrade of SwaggerCodegen will also fix #340.

@brendandburns

This comment has been minimized.

Collaborator

brendandburns commented Nov 13, 2018

@davidxia unfortunately, I don't think that PR fixes this issue. The object in question here is a Map and so I think it still calls Objects.equal(...)

Looking at the code, I think the right answer is to use Objects.deepEquals(...) here instead of Objects.equals(...)

https://docs.oracle.com/javase/7/docs/api/java/util/Objects.html#deepEquals(java.lang.Object,%20java.lang.Object)

We should do a PR into swagger-code to update to deepEquals

@davidxia

This comment has been minimized.

Contributor

davidxia commented Nov 14, 2018

I took a closer look at this and it seems Object.deepEquals() won't work either. I assume you were thinking about having the deepEquals() here?

Objects.equals(this.data, v1Secret.data) &&

This will go here

return Arrays.deepEquals0(a, b);

which, because a and b are LinkedHashMaps, will reach this with e1 and e2 being the same LinkedHashMaps.

 eq = e1.equals(e2);

false is finally returned from here because value and m.get(key) are the byte[]. This is where deepEquals() would've worked.

if (!value.equals(m.get(key)))
    return false;

So I think using both Objects.equals() and Objects.deepEquals() will end up at that line above. I don't see any straightforward fixes to this right now...

I created a failing test here and an example of how Objects.deepEquals() fails here.

@brendandburns

This comment has been minimized.

Collaborator

brendandburns commented Nov 14, 2018

Wow, that's really unfortunate. It feels like a bug in the Java code, I would have expected deepEquals of two maps with the same keys and the same values to return true...

We could in theory hack up the swagger codegen to detect maps and do the right thing here itself (recursively, of course).

It feels like a lot of work for small payoff, but we can keep the issue open in case someone wants to take it up...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment