Cycle Finder Tool

Nutzung

Hier ist ein einfaches Beispiel mit einem Zyklus zwischen zwei Klassen, Foo und Bar.

cat Foo.java
package mypkg;
public class Foo {
  Bar myBar;
}

cat Bar.java
package mypkg;
public class Bar {
  Foo myFoo;
}

cycle_finder Foo.java Bar.java
acceptAST: mypkg/Bar.java
acceptAST: mypkg/Foo.java

***** Found reference cycle *****
Bar -> (field myFoo with type Foo)
Foo -> (field myBar with type Bar)
----- Full Types -----
Lmypkg/Bar;
Lmypkg/Foo;

1 CYCLES FOUND.

In der Ausgabe sehen Sie zuerst acceptAST für jede zu geparste Java-Datei. Diese Protokollierung ist lediglich informativ.

Für jeden Zyklus werden zwei Listen gedruckt. Die erste Liste enthält eine Beschreibung des Zyklus. Jede Linie listet eine Kante in der Referenzgrafik auf. Die Edge-Beschreibung zeigt den Ursprungstyp an, gefolgt von einer Beschreibung, wie sich der Ursprungstyp auf den Zieltyp beziehen kann.

Die zweite Liste unter Full Types enthält die eindeutigen Typschlüssel für jeden Typ im Zyklus. Dies ist nützlich, da es das vollständige Paket jedes Typs liefert.

Listen unterdrücken

Bei einigen erkannten Zyklen ist keine Korrekturmaßnahme erforderlich. Dies kann daran liegen, dass der Zyklus langlebige Objekte enthält, die nicht freigegeben werden müssen. Oder das Tool erkennt einen theoretischen Zyklus basierend auf den Typen bestimmter Felder, in dem nachgewiesen werden kann, dass die beteiligten Objekte nie einen Zyklus bilden werden. In diesen Fällen können wir Dateien mit Unterdrücken-Liste verwenden, um diese Zyklen nicht zu melden.

Das Tool akzeptiert Dateien zur Unterdrückung von Listen mit der Option --suppress-list. Dateien mit Suppress-Listen sind reine Textdateien, die einzeilige Einträge enthalten. Ein Eintrag für eine unterdrückende Liste kann in einer der vier Formen dargestellt werden, die im folgenden Beispiel gezeigt werden. Es wird empfohlen, beim Hinzufügen von Einträgen aus der Liste der Unterdrückungsliste so spezifisch wie möglich zu sein, um eine Unterdrückung eines legitimen Zyklus zu vermeiden. Kommentare können mit dem Zeichen „#“ hinzugefügt werden.

# Specifies that "fieldA" in ClassA will not refer to any object that is a subtype of ClassB.
FIELD my.pkg.ClassA.fieldA my.pkg.ClassB

# Suppresses all cycles containing "fieldA" in ClassA.
FIELD my.pkg.ClassA.fieldA

# Suppresses all cycles containing any field of ClassA.
TYPE my.pkg.ClassA

# Suppress all cycles containing the Inner's outer reference to ClassA.
OUTER my.pkg.ClassA.Inner

# Suppress all cycles containing the outer reference from an anonymous class declared in myMethod.
OUTER my.pkg.ClassA.myMethod.$

# Suppresses all cycles containing any type in package "my.pkg".
NAMESPACE my.pkg