2016-03-09 2 views
0

Для данной банки я хочу узнать все классы (насколько это возможно), которые используются этой банкой. Поскольку у меня много банок, я хочу автоматизировать этот процесс. Моя лучшая идея покаПолучение всех импортированных классов для баночки

  1. Декомпилировать банку (у меня нет опыта с этим, но там должны быть инструменты командной строки).
  2. Ищите импорт и разбирайте их.

Но я надеюсь, что кто-то еще сделал что-то подобное раньше и дайте мне совет по этому поводу.

+0

Для «используемых» этой баночкой вы подразумеваете «содержащиеся» этой банкой? –

+0

Я думаю, что он только те, которые на самом деле используются где-то в исходном коде (отсюда его анализ идеи импорта) –

+0

@DavideLorenzoMARINO Нет. Я знаю, что легко узнать, какие классы содержатся в банке. Я хочу знать, какие классы используются, то есть импортировать или вызывать через квалифицированное имя. –

ответ

2

Использование специализированного инструмента - это, вероятно, способ сделать это надежно.

Однако один действительно Janky способ сделать это было бы, чтобы захватить список всех .class файлов в вашем JAR, положить JAR на пути к классам и использовать javap, чтобы получить ссылки на другие классы:

#!/usr/bin/env bash 
javap -cp $1 -v \ 
    `zipinfo -1 $1 '*.class' | sed 's:/:.:g' | sed 's:\.class$::'` | \ 
    grep ' = Class' | sed 's:.*// ::' | sort | uniq 

Запуск этого на guava-19.0.jar дает this:

"[[B" 
"[B" 
"[[C" 
"[C" 
com/google/common/annotations/Beta 
com/google/common/annotations/GwtCompatible 
com/google/common/annotations/GwtIncompatible 
com/google/common/annotations/VisibleForTesting 
com/google/common/base/Absent 
com/google/common/base/AbstractIterator 
............................................................... 
"[Lcom/google/common/util/concurrent/MoreExecutors$DirectExecutor;" 
"[Lcom/google/common/util/concurrent/Service$State;" 
"[Lcom/google/thirdparty/publicsuffix/PublicSuffixType;" 
"[Ljava/io/File;" 
"[[Ljava/lang/annotation/Annotation;" 
"[Ljava/lang/annotation/Annotation;" 
"[Ljava/lang/Class;" 
"[Ljava/lang/Comparable;" 
"[Ljava/lang/Enum;" 
"[[Ljava/lang/Object;" 
"[Ljava/lang/Object;" 
"[Ljava/lang/reflect/Field;" 
"[Ljava/lang/reflect/Method;" 
"[Ljava/lang/reflect/Type;" 
"[Ljava/lang/reflect/TypeVariable;" 
"[Ljava/lang/StackTraceElement;" 
"[Ljava/lang/String;" 
"[Ljava/net/URL;" 
"[Ljava/util/Iterator;" 
"[Ljava/util/Map$Entry;" 
"[[S" 
"[S" 
sun/misc/Unsafe 
"[[Z" 
"[Z" 

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

Как это работает:

zipinfo -1 $1 '*.class' напечатает имена всех файлов в .class$1, что аргумент сценария показан. sed s смените / s на . s и удалите расширение .class, чтобы вы получили список имен классов в стиле Java. Вы могли бы сделать это более элегантно, но это должно сработать.

Задание javap ставит банку на путь класса -cp и передает все классы. -v выводит много информации, включая некоторые записи, которые представляют ссылки на имена классов. grep гарантирует, что мы только смотрим на них, sed удаляет дополнительную информацию, которая нам не интересна. sort | uniq гарантирует, что мы не будем печатать имя какого-либо класса более одного раза. Для стандартизации формата вывода требуется немного больше sed.

+0

Можете ли вы дать мне краткое объяснение, что делает ваша «магия командной строки»? –

+0

добавлено изменение с дополнительной информацией – Vlad

0

Простым способом является попытка скомпилировать ваш код, не добавляя эту банку.

Попытайтесь скомпилировать и посмотреть на ошибки компилятора - это самый быстрый способ сделать это.

Но помните, что класс может быть загружен также с использованием отражения (например, через файлы конфигурации пружины), а компиляция кода без флага не будет информировать вас о потенциальных ошибках во время выполнения.

+0

Это не то, что я хочу. Я хочу написать программу, в которой я даю длинный список баннеров (скажем, 100), и возвращает для каждого из них список банки, которые «используются» (импортированные и т. Д., Отражение может быть проигнорировано). –

+0

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

+0

Не банки, а классы. Если я, например, открыть jar в jd-gui (декомпилятор), я вижу декомпилированный импорт различных исходных файлов. –

Смежные вопросы