Проверка использования кода Java - PullRequest
5 голосов
/ 20 апреля 2009

Я работаю над библиотекой, в которой мы хотим определить, какая часть нашей библиотеки используется. И.Е. мы хотим знать, сколько методов в нашей библиотеке являются открытыми, но никогда не вызываться.

Цель: Статический анализ Определите, сколько строк кода вызывает каждый открытый метод в пакете A в текущем проекте. Если количество вызовов равно нулю, метод должен быть указан как таковой.

Ответы [ 10 ]

9 голосов
/ 02 июня 2009

Я полагаю, вы ищете этот плагин Eclipse -> UCDetector

Из документации (обратите внимание на второй пункт маркера)

  • Ненужный (мертвый) код
  • Код, в котором видимость может быть изменена на защищенную, по умолчанию или частный
  • Методы полей, которые могут быть окончательными

В большем масштабе, если вы хотите выполнить статический анализ на уровне объектов, посмотрите на этот инструмент из IBM -> Structural Analysis for Java . Это действительно полезно для анализа объектов библиотек, API и т. Д.

3 голосов
/ 02 июня 2009

Использование клиентом отражающих вызовов - это одна дыра в статическом анализе, которую следует учитывать. Поскольку нет никакого способа узнать наверняка, что определенный метод не вызывается через какую-то причудливую схему отражения. Так что, может быть, лучше всего использовать сочетание времени выполнения и статического анализа.

3 голосов
/ 20 апреля 2009

Не совсем то, что вы ищете, но:

Нечто подобное можно сделать с помощью инструментов покрытия кода (например, Cobertura ). Они не выполняют статическую проверку исходного кода, но используют байт-код для сбора метрик во время выполнения. Конечно, вам нужно управлять приложением так, чтобы оно использовало все шаблоны использования и могло пропустить более редкие пути кода.

Что касается статического анализа, возможно, эти инструменты могут вам помочь (проект Apache использует их для проверки совместимости API для новых выпусков, похоже, что эта задача в некоторой степени связана с тем, что вы пытаетесь сделать):

  • Clirr - это инструмент, который проверяет библиотеки Java на двоичную и исходную совместимость со старыми выпусками. По сути, вы предоставляете ему два набора jar-файлов, а Clirr выводит список изменений в общедоступном API.
  • JDiff - это доклет Javadoc, который генерирует HTML-отчет обо всех пакетах, классах, конструкторах, методах и полях, которые были удалены, добавлены или изменены любым способом, включая их документацию, когда два API сравниваются.
1 голос
/ 08 июня 2009

Пожалуйста, посмотрите на Детектор мертвого кода . Он утверждает, что делает именно то, что вы ищете: поиск неиспользуемого кода с помощью статического анализа.

1 голос
/ 06 июня 2009

IntelliJ имеет инструмент для обнаружения методов, полей, классов, которые могут иметь более ограниченные модификаторы. Он также имеет быстрое решение применить эти изменения, которые также могут сэкономить вам много работы. Если вы не хотите платить за это, вы можете получить 30-дневную бесплатную лицензию, которая более чем достаточна для изменения кода, но это не то, что вам нужно делать очень часто.

Кстати: IntelliJ имеет около 650 проверок кода для улучшения качества кода, около половины имеет автоматические исправления, поэтому я советую потратить пару дней, используя его для реорганизации / исправления кода.

1 голос
/ 20 апреля 2009

Я бы предложил, чтобы JDepend показывал вам зависимости между пакетами и классами, отлично, чтобы найти циклические зависимости! http://clarkware.com/software/JDepend.html (имеет плагин Eclipse: http://andrei.gmxhome.de/jdepend4eclipse/

, а также PMD для других показателей http://pmd.sourceforge.net/

1 голос
/ 20 апреля 2009

Не думаю, что вы можете измерить, как часто "нужен" класс или функция.
Есть несколько простых вопросов:

  • Что определяет, является ли статистика использования вашей игровой библиотеки "нормальной" или "выбросом"? Разве неправильно убивать себя в игре слишком часто? Вы бы чаще использовали класс killScreen, как хороший геймер.
  • Что определяет "много"? Время или счет использования? POJO будут занимать редкое время, но используются довольно часто.

Вывод:
Я не знаю, чего вы пытаетесь достичь.
Если вы хотите отобразить свои зависимости кода, для этого есть другие инструменты . Если вы пытаетесь измерить выполнение кода, для Java есть профилировщик или эталонные тесты . Если вы фанат статистики, вы будете довольны RapidMiner ;)

Удачи с этим!

0 голосов
/ 06 июня 2009

Вы можете написать свою собственную утилиту для этого (через несколько часов после прочтения), используя библиотеку анализа байт-кода ASM (http://asm.ow2.org).). Вам потребуется реализовать ClassVisitor и MethodVisitor. Вы будете использовать ClassReader проанализировать файлы классов в вашей библиотеке.

  • Ваш метод ClassVisitor visitMethod (..) будет вызываться для каждого объявленного метода.
  • Ваш MethodVisitor's visitMethodInsn (..) будет вызываться для каждого вызываемого метода.

Ведение карты для подсчета. Ключи представляют методы (см. Ниже). Вот некоторый код:

class MyClassVisitor {
    // ...
    public void visit(int version, int access, String name, ...) {
        this.className = name;
    }
    public MethodVisitor visitMethod(int access, String name, String desc, ...):
        String key = className + "." + name + "#" + desc;
        if (!map.containsKey() {
            map.put(key, 0);
        }
        return new MyMethodVisitor(map);
    }
    // ...
}

void class MyMethodVisitor {
    // ...
    public visitMethodInsn(int opcode, String name, String owner, String desc, ...) {
        String key = owner + "." + name + "#" + desc;
        if (!map.containsKey() {
            map.put(key, 0);
        }
        map.put(key, map.get(key) + 1);
    }
    // ...
}

В основном это все. Вы начинаете шоу с чем-то вроде этого:

Map<String,Integer> map = new HashMap<String,Integer>();
for (File classFile : my library) {
    InputStream input = new FileInputStream(classFile);
    new ClassReader(input).accept(new MyClassVisitor(map), 0);
    input.close();
}
for (Map.Entry<String,Integer> entry : map.entrySet()) {
    if (entry.getValue() == 0) {
        System.out.println("Unused method: " + entry.getKey());
    }
}

Наслаждайтесь!

0 голосов
/ 05 июня 2009

Proguard тоже может быть вариантом (http://proguard.sourceforge.net/):

"Некоторые варианты использования ProGuard:

  • ...
  • Перечисление мертвого кода, поэтому его можно удалить из исходного кода.
  • ... "

См. Также http://proguard.sourceforge.net/manual/examples.html#deadcode

0 голосов
/ 20 апреля 2009

Вот несколько списков инструментов покрытия кода Java. Я не использовал ни один из них лично, но это может помочь вам начать:

...