Comment made by: alexmiller
In the first case, -10000000000000 is a long and the compiler unambiguously finds Math.abs(long).
In the second case, a is an Object and all abs signatures are considered (this is in Reflector.invokeMatchingMethod). In both Java 1.7 and 1.8, the long and int signatures are found "congruent".
In Java 1.7, the long version is found first and treated as a match, then int is checked and Compiler.subsumes((link: int), (link: long)) returns false, leading to the long method being kept as the match.
In Java 1.8, the int version is found first and treated as a match, then long is checked and Compiler.subsumes((link: long), (link: int)) returns false, leading to the int method being kept as the match.
Both of these return false on both JDKs:
(Compiler/subsumes (into-array [Long/TYPE]) (into-array [Integer/TYPE]))
(Compiler/subsumes (into-array [Integer/TYPE]) (into-array [Long/TYPE]))
so the real difference is just the ordering that is considered, which is JDK-specific.
The considered signatures could be sorted in some canonical way making this behavior consistent, or could maybe express a preference between the two signatures somehow.
In any case, getting rid of the reflection here by hinting or casting a resolves the problem - it should be considered only luck not intention that the correct results comes out with Java 7 in this case, I think.