Поиск цикла Инструмент

Применение

Вот простой пример с циклом между двумя классами, Foo и 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.

В выводе вы сначала увидите acceptAST для каждого анализируемого Java-файла. Это просто информативный журнал.

Для каждого цикла будет распечатано два списка. Первый список содержит описание цикла. В каждой строке указано ребро эталонного графа. В описании ребра будет показан тип источника, за которым следует описание того, как тип источника может относиться к целевому типу.

Второй список в разделе Full Types показывает уникальные ключи типов для каждого типа в цикле. Это полезно, поскольку предоставляет полный пакет каждого типа.

Подавить списки

Некоторые обнаруженные циклы не потребуют никаких корректирующих действий. Это может быть связано с тем, что цикл содержит долгоживущие объекты, которые не нужно освобождать. Или инструмент может обнаружить теоретический цикл на основе типов определенных полей, где доказано, что задействованные объекты никогда не образуют цикл. В этих случаях мы можем использовать файлы списков подавления, чтобы не сообщать об этих циклах.

Инструмент принимает файлы списков подавления с помощью опции --suppress-list . Файлы подавляющих списков представляют собой обычные текстовые файлы, содержащие однострочные записи. Запись подавляющего списка может принимать одну из 4 форм, показанных в примере ниже. Рекомендуется при добавлении записей подавляющего списка быть как можно более конкретными, чтобы избежать подавления допустимого цикла. Комментарии можно добавлять с помощью символа «#».

# 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