Thursday, 28 April 2016

java.lang.IllegalArgumentException: Comparison method violates its general contract!

I got the error message in the title whilst using Flyway to run database scripts at work1.

I find it very satisfying that sorting methods in the JDK can detect if your comparer is not obeying the contract.

There are a lot of errors that cause the contract to be violated according to [2].

Here are the rules in short as described in [3]:
  • sign(compare(x,y)) == -sign(compare(y,x))
  • (compare(x, y)>0) && (compare(y, z)>0)) implies compare(x, z)>0 (transitivity)
  • compare(x, y)==0 implies that sgn(compare(x, z))==sgn(compare(y, z))
Sounds like an excellent starting point for some good JUnit Tests.

References

[1] GitHub - Flyway - Issue 1249
https://github.com/flyway/flyway/issues/1249
[2] StackOverflow - “Comparison method violates its general contract!”
http://stackoverflow.com/questions/8327514/comparison-method-violates-its-general-contract
[3] Oracle Javadoc - Interface Comparator>T>
https://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html

Thursday, 21 April 2016

Constructors, Javadoc and Inheritance

I recently had the problem that I defined some very good javadoc documentation on a constructor in one of my generic classes that is inherited a lot.

The documentation, however, is never propagated to subclasses, because constructors are not inherited1.

It is too bad that I already have to duplicate Constructors in my subclasses, but now I have to duplicate the documentation as well?

Right now, the best solution I can think of is to add a "@see" link to the appropriate super constructor. Like so:

There is a feature request/bug2 defined to expand the {inheritedDoc} to also work on constructors. But it has not seen any love for a long time.

References

[1] StackOverflow - Why is inheritedDoc not defined on constructors?
http://stackoverflow.com/questions/14848999/why-is-inheriteddoc-not-defined-on-constructors
[2] JDK-4810216 : Allow {@inheritDoc name} for constructors
http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4810216