Search code examples
nullpointerexceptionxtend

XTend null safe throws NullPointerException


I am porting my template code to XTend. At some point I have this type of condition handling in a test case:

@Test
def xtendIfTest() {
    val obj = new FD
    if (true && obj?.property?.isNotNull) {
        return
    }
    fail("Not passed")
}

def boolean isNotNull(Object o) {
    return o != null
}
class FD {
 @Accessors
 String property
}

This works as expected as the property is null and the test will fail with "Not passed" message. But a simple change in the return type of isNotNull method to Boolean (wrapper):

def Boolean isNotNull(Object o) {
    return o != null
}

fails with a NullPointerException. Examining the generated java code for this I can see that XTend is using an intermediate Boolean object expression and that is the cause of NPE. Am I missing the point of the XTend null safe operator (?.) or I can't use a method like this after the operator?

Thanks.


Solution

  • The operator behaves properly. The exception is thrown because of the usage of a Boolean in an if-expression, which requires auto-unboxing.

    If you try the following:

    @Test
    def xtendIfTest() {
        val Boolean obj = null
        if (obj) {
            return
        }
        fail("Not passed")
    }
    

    You will also run into a NullPointerException.

    This is consistent with the Java Language Specification (https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.8) - when auto-unboxing is required this can yield a NullPointerException:

    @Test
    public void test() {
        Boolean value = null;
        if (value) { // warning: Null pointer access: This expression of type Boolean is null but requires auto-unboxing
            // dead code
        }
    }
    

    Hope that helps.