2014-05-22 4 views
15

Mam problem zgłoszony przez FindBugs ale wiem lepiej :) patrz poniższy przykład:Jak ustawić filtr FindBugs dla pól z określoną adnotacją?

public class MyClass extends BaseClass { 

    @CustomInjection 
    private Object someField; 

    public MyClass() { 
     super(); 
     someField.someMethod(); // Bug is here because FindsBugs thinks this is always null 
    } 
} 

W moim konstruktora klasy bazowej I wstrzyknąć wszystkie pola z dopiskiem @CustomInjection z właściwego obiektu, więc moje pola są adnotacją not null w moim przypadku.

Nie chcę ukrywać ostrzeżenia za pomocą "suppresswarning", ponieważ spowoduje to zaśmiecenie kodu. Wolę, aby filtr, taki jak findbugs, wyjaśnił here, ale nie mogę znaleźć sposobu na filtrowanie błędów w polach z przypisami do określonego interfejsu. Nie chcę również filtrować wszystkich ostrzeżeń o błędach o zerowym błędzie. Myślę, że powinno być coś takiego:

<Match> 
    <Bug code="UR"> 
    <Field annotation="CustomInjection"> 
</Match> 
+0

Dobre pytanie! Nie sądzę jednak, żeby było to możliwe. Rozwiązaniem może być napisanie niestandardowego detektora, który najpierw sprawdza skonfigurowane adnotacje, a następnie wywołuje oryginalny detektor (powiedzmy 'FilteringDetector'). Filtry niestandardowe będą lepiej pasować, ale te też nie istnieją. –

Odpowiedz

5

Znalazłem sposób rozwiązania tego problemu. Wydaje wykrywanie oparte na wstrzyknięciu adnotacji jest zakodowana w FindBugs, zobacz ten kawałek kodu źródłowego:

public static boolean isInjectionAttribute(@DottedClassName String annotationClass) { 
    if (annotationClass.startsWith("javax.annotation.") 
      || annotationClass.startsWith("javax.ejb") 
      || annotationClass.equals("org.apache.tapestry5.annotations.Persist") 
      || annotationClass.equals("org.jboss.seam.annotations.In") 
      || annotationClass.startsWith("javax.persistence") 
      || annotationClass.endsWith("SpringBean") 
      || annotationClass.equals("com.google.inject.Inject") 
      || annotationClass.startsWith("com.google.") && annotationClass.endsWith(".Bind") 
      && annotationClass.hashCode() == -243168318 
      || annotationClass.startsWith("org.nuxeo.common.xmap.annotation") 
      || annotationClass.startsWith("com.google.gwt.uibinder.client") 
      || annotationClass.startsWith("org.springframework.beans.factory.annotation") 
      || annotationClass.equals("javax.ws.rs.core.Context")) { 
     return true; 
    } 
    int lastDot = annotationClass.lastIndexOf('.'); 
    String lastPart = annotationClass.substring(lastDot + 1); 
    if (lastPart.startsWith("Inject")) { 
     return true; 
    } 
    return false; 
} 

Więc jak @EJB adnotacje nie są pokazane jako UR błędów ale moja adnotacja @CustomInjection zawsze będzie bug UR.

Ale na końcu funkcji znajduje się ucieczka dla wszystkich nazw adnotacji zaczynających się od "Inject", więc jeśli zmienię nazwę @CustomInjection na @InjectCustom, błąd UR zniknie. Aby uniknąć tego problemu, zmień nazwę adnotacji na @InjectSomething.

1

Jeśli nie można tego zrobić bezpośrednio, napisać pre-procesor, który wykrywa adnotacji i generuje kod, który inicjuje pole z czegoś, co czyni jego wygląd ważny do zastosowań FindBugs. Podaj wyjście pre-procesora do FindBugs, zamiast oryginalnego kodu źródłowego.