animal-sniffer icon indicating copy to clipboard operation
animal-sniffer copied to clipboard

Fail to detect usage of unsupported type as inner class implementation

Open snicoll opened this issue 9 years ago • 3 comments

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!

snicoll avatar Jan 18 '16 10:01 snicoll

Wasn't there something special with static classes? Does animal-sniffer detect this with a non-static class?

rfscholte avatar Feb 21 '16 16:02 rfscholte

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.

jglick avatar Dec 15 '16 16:12 jglick

In particular CheckingVisitor.visit seems to be ignoring its superName and interfaces arguments.

jglick avatar Dec 15 '16 16:12 jglick