Für statische Analysetools verwende ich häufig CPD, PMD , FindBugs und Checkstyle .
CPD ist das PMD-Tool "Copy / Paste Detector". Ich habe PMD eine Weile verwendet, bevor ich den Link "Finding Duplicated Code" auf der PMD-Webseite bemerkte .
Ich möchte darauf hinweisen, dass diese Tools manchmal über ihre "out-of-the-box" -Regeln hinaus erweitert werden können. Und das nicht nur, weil sie Open Source sind, damit Sie sie neu schreiben können. Einige dieser Tools werden mit Anwendungen oder "Hooks" geliefert, mit denen sie erweitert werden können. Zum Beispiel wird PMD mit dem "Designer" -Tool geliefert, mit dem Sie neue Regeln erstellen können. Außerdem verfügt Checkstyle über die DescendantToken- Prüfung mit Eigenschaften, die eine umfassende Anpassung ermöglichen.
Ich integriere diese Tools in einen Ant-basierten Build . Sie können dem Link folgen, um meine kommentierte Konfiguration zu sehen.
Zusätzlich zur einfachen Integration in den Build finde ich es hilfreich, die Tools so zu konfigurieren, dass sie auf verschiedene andere Arten etwas "integriert" sind. Gleichmäßigkeit der Berichterstellung und der Unterdrückung von Warnungen. Ich möchte diese Aspekte zu dieser Diskussion hinzufügen (die wahrscheinlich auch das Tag "statische Analyse" haben sollte): Wie konfigurieren die Leute diese Tools, um eine "einheitliche" Lösung zu erstellen? (Ich habe diese Frage hier separat gestellt )
Zunächst transformiere ich für Warnberichte die Ausgabe so, dass jede Warnung das einfache Format hat:
/absolute-path/filename:line-number:column-number: warning(tool-name): message
Dies wird oft als "Emacs-Format" bezeichnet, aber selbst wenn Sie Emacs nicht verwenden, ist es ein vernünftiges Format zum Homogenisieren von Berichten. Beispielsweise:
/project/src/com/example/Foo.java:425:9: warning(Checkstyle):Missing a Javadoc comment.
Meine Transformationen des Warnformats werden von meinem Ant-Skript mit Ant- Filterketten durchgeführt .
Die zweite "Integration", die ich mache, dient der Unterdrückung von Warnungen. Standardmäßig unterstützt jedes Tool Kommentare oder Anmerkungen (oder beides), die Sie in Ihren Code einfügen können, um eine Warnung auszuschalten, die Sie ignorieren möchten. Diese verschiedenen Anforderungen zur Unterdrückung von Warnungen sehen jedoch nicht einheitlich aus, was etwas albern erscheint. Wenn Sie eine Warnung unterdrücken, unterdrücken Sie eine Warnung. Warum also nicht immer " SuppressWarning
?"
Beispielsweise unterdrückt die Standardkonfiguration von PMD die Generierung von Warnungen in Codezeilen mit der Zeichenfolge " NOPMD
" in einem Kommentar. Außerdem unterstützt PMD die @SuppressWarnings
Annotation von Java . Ich konfiguriere PMD so, dass Kommentare verwendet werden, die " SuppressWarning(PMD.
" enthalten, anstatt NOPMD
dass PMD-Unterdrückungen gleich aussehen. Ich fülle die bestimmte Regel aus, gegen die bei Verwendung der Unterdrückung des Kommentarstils verstoßen wird:
// SuppressWarnings(PMD.PreserveStackTrace) justification: (false positive) exceptions are chained
Nur der SuppressWarnings(PMD.
Teil " " ist für einen Kommentar von Bedeutung, stimmt jedoch mit der Unterstützung von PMD für die @SuppressWarning
Anmerkung überein, mit der einzelne Regelverletzungen namentlich erkannt werden:
@SuppressWarnings("PMD.CompareObjectsWithEquals") // justification: identity comparision intended
In ähnlicher Weise unterdrückt Checkstyle die Generierung von Warnungen zwischen Kommentarpaaren (es wird keine Unterstützung für Anmerkungen bereitgestellt). Standardmäßig Kommentare Check aus und enthalten die Saiten zu drehen CHECKSTYLE:OFF
und CHECKSTYLE:ON
sind. Durch Ändern dieser Konfiguration (mit Checkstyles "SuppressionCommentFilter") zur Verwendung der Zeichenfolgen " BEGIN SuppressWarnings(CheckStyle.
" und " END SuppressWarnings(CheckStyle.
" sehen die Steuerelemente eher wie PMD aus:
// BEGIN SuppressWarnings(Checkstyle.HiddenField) justification: "Effective Java," 2nd ed., Bloch, Item 2
// END SuppressWarnings(Checkstyle.HiddenField)
Mit Check Kommentaren, die bestimmte Kontrollverletzung ( HiddenField
) ist von Bedeutung , da jede Überprüfung sein eigenes „hat BEGIN/END
“ Kommentar Paar.
FindBugs unterstützt auch die Unterdrückung der Warnungsgenerierung mit einer @SuppressWarnings
Anmerkung, sodass keine weitere Konfiguration erforderlich ist, um ein gewisses Maß an Einheitlichkeit mit anderen Tools zu erreichen. Leider muss Findbugs eine benutzerdefinierte @SuppressWarnings
Annotation unterstützen, da die integrierte Java- @SuppressWarnings
Annotation eine SOURCE
Aufbewahrungsrichtlinie enthält, die nicht stark genug ist, um die Annotation in der Klassendatei beizubehalten, in der FindBugs sie benötigt. Ich qualifiziere die Unterdrückung von FindBugs-Warnungen vollständig, um Konflikte mit der @SuppressWarnings
Annotation von Java zu vermeiden :
@edu.umd.cs.findbugs.annotations.SuppressWarnings("UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR")
Diese Techniken lassen die Dinge zwischen den Werkzeugen einigermaßen konsistent aussehen. Beachten Sie, dass jede Warnungsunterdrückung die Zeichenfolge " SuppressWarnings
" enthält, was es einfach macht, eine einfache Suche durchzuführen, um alle Instanzen für alle Tools über eine gesamte Codebasis zu finden.