javaapachemavenapache-commonsapache-commons-lang3

Ambiguous compilation error with Maven and apache utils


I'm using org.apache.commons.lang3.BooleanUtils in the commons-lang3 (version 3.1). When I try to compile next line of code

BooleanUtils.xor(true, true);

using maven-compiler-plugin (version 3.3), I'm getting a compilation failure message:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.3:compile (default-compile) on project exchange: Compilation failure
[ERROR] MyClass.java:[33,34] reference to xor is ambiguous, both method xor(boolean...) in org.apache.commons.lang3.BooleanUtils and method xor(java.lang.Boolean...) in org.apache.commons.lang3.BooleanUtils match

I use Java 1.7.0_55 to compile.

How can I solve this?


Solution

  • The problem happens because the signature of the method has variable arguments. When a method is invoked, there are 3 phases during which all applicable methods are searched. Methods with variable arguments are searched in phase 3 where boxing, and unboxing is also allowed.

    So both xor(boolean...) and xor(Boolean...) are applicable here because boxing is taken into account. When multiple methods are applicable, only the most specific is invoked. But in this case, boolean and Boolean can't be compared, so there is no more specific method, hence the compiler error: both methods match.

    A workaround is to create an explicit array:

    public static void main(String[] args) {
        xor(new boolean[] { true, false }); // will call the primitive xor
        xor(new Boolean[] { Boolean.TRUE, Boolean.FALSE }); // will call the non-primitive xor
    }
    
    private static Boolean xor(Boolean... booleans) {
        System.out.println("Boolean...");
        return Boolean.TRUE;
    }
    
    private static boolean xor(boolean... booleans) {
        System.out.println("boolean...");
        return true;
    }