Я пытаюсь получить все зависимости в классе Java, включая классы, используемые для параметризации обобщений и типов локальных переменных. Пока что лучшая структура, которую я нашел, - apache bcel. Используя его, я могу легко найти все поля, аргументы метода и локальные переменные из байтового кода. В основном все, кроме типов дженериков и локальных переменных. Например, из строки List<Point> points = new ArrayList<Point>();
я могу найти только одну зависимость - ArrayList с использованием метода JavaClass.getConstantPool()
из bcel. Он не может обнаружить ни интерфейс List, ни класс Point. Я также пробовал tattletale и CDA, к сожалению, без успеха (те же результаты). Изучение импорта недостаточно - мне нужны также зависимости от одного и того же пакета, и я не могу принять подстановочные знаки. Я был бы признателен за любую помощь.Найти все зависимости в Java-классе
ответ
Я наконец нашел решение. ASM Bytecode Framework
- правильный инструмент для использования. Используя официальный tutorial и правый example, довольно легко получить все необходимые зависимости. В примере уже есть класс посетителей DependencyVisitor
, который делает то, что я хочу. Чтобы получить правильное форматирование, я должен был изменить только один метод в DependencyVistitor
пример кода, поэтому он добавляет полные имена классов вместо пакетов только:
private String getGroupKey(String name)
{
//Just comment that block so you can get full class names instead of package only
/*
int n = name.lastIndexOf('/');
if (n > -1)
{
name = name.substring(0, n);
}
*/
// Replace resource char with package separator char
packages.add(name.replace("/", "."));
//packages.add(name);
return name;
}
Глядя на DependencyVisitor
код, который вы можете легко понять, что она делает, и изменить его к вашему необходимо. Запуск его в моем классе классов дает мне приятный, полезный вывод: [java.util.ArrayList, java.lang.Object, java.util.List, java.awt.Point, goobar.test.asmhello.TestClass, java.lang.String, java.lang.Integer, java.awt.Graphics, goobar.test.asmhello.TestClass2]
. Он содержит каждый класс и интерфейс, которые я использовал, и каждый тип, используемый для параметризации дженериков.
отлично, не было такой проблемы раньше, обычно идентифицировать по аннотации, но это круто, спасибо –
Пример кода переместился [здесь] (http://websvn.ow2.org/listing.php?repname=asm&path =% 2Ftrunk% 2Fasm% 2Fexamples% 2Fdependencies% 2Fsrc% 2Forg% 2Fobjectweb% 2Fasm% 2Fdepend% 2F). – seanf
Вы пытаетесь сделать это во время выполнения из байт-кода? Во время компиляции? –
Я хочу найти все статические зависимости (не время выполнения). Чтение байт-кода, вероятно, является лучшей идеей для этого. Но я также могу попытаться разобрать исходный код (это просто не кажется лучшей идеей, и я не нашел для этого никакого решения). – goobar
Не все исходные зависимости должны заканчиваться в файле класса (общие типы внутри метода, встроенные константы). Просто посмотрите на файлы классов в достойном текстовом редакторе или на UNIX 'strings'. –