animal-sniffer
animal-sniffer copied to clipboard
Fail to detect usage of unsupported type as inner class implementation
We are using Animal Sniffer on the Spring Framework to check that we don't use any Java7 or 8 API in our code base (except in specific areas that are guarded). A recent contribution uses java.util.function.Function
and did not report any specific issue (while it should have).
Here is a sample that illustrates the problem:
public class Whatever {
@UsesJava8
private static class FunctionFoo {
public static void foo() {
Function<Object, Object> f = new MyFunc();
f.apply(null);
}
}
private static class MyFunc implements Function<Object,Object> {
@Override
public Object apply(Object o) {
return null;
}
}
}
@UsesJava8
is our special marker to flag an exception. If I remove that annotation, animal sniffer reports an error on f.apply(null)
:
[ant:animalSniffer] /Users/snicoll/workspace/pivotal/spring-framework/spring-beans/build/classes/main/org/springframework/beans/Whatever$FunctioFoo.class:1065: Undefined reference: Object java.util.function.Function.apply(Object)
But the MyFunc
is left unnoticed while it's using Function
. Did I overlooked something? Thanks!
Wasn't there something special with static classes? Does animal-sniffer detect this with a non-static class?
To verify Animal Sniffer was working with
<dependency>
<groupId>org.codehaus.mojo.signature</groupId>
<artifactId>java17</artifactId>
<version>1.0</version>
<type>signature</type>
</dependency>
I tried adding the following to a class in my project (in a simple method in a top-level class):
Supplier<Object> s = new Supplier<Object>() {
public Object get() {
throw new UnsupportedOperationException();
}
};
There was no error, despite the fact that this is using a Java 8 API, and javap
confirmed that the bytecode contained
class …$1 implements java.util.function.Supplier<java.lang.Object> {
Adding
Clock clock = Clock.systemUTC();
produces the expected failure.
I suspect that the visitor is failing to check types mentioned in implements
clauses, which is the only place a Java 8 type is used in the false positive.
In particular CheckingVisitor.visit
seems to be ignoring its superName
and interfaces
arguments.