[devel] Java autoreq/autoprov draft

Damir Shayhutdinov =?iso-8859-1?q?damir_=CE=C1_altlinux=2Eorg?=
Ср Фев 7 01:21:37 MSK 2007


> А разве нельзя залезать в .jar, разбирать .class файлы и находить все
> объекты, которые в них используются? Так получится Requires.
> А Provides вообще получаются анализом содержимого .jar файла.
>
> Примеры зависимости: Java(org.apache.xpath.XPath)
> Правда получится довольно много этих самых Provides и Requires :( Зато
> автоматом.
Появилась идея получше. Так как минимальной файловой единицей в Java
является .jar-файл, то Provides/Requires можно в принципе
организовывать на них.

Вот например в пакете jakarta-oro

rpm -ql jakarta-oro | fgrep .jar
/usr/share/java/jakarta-oro.jar

находится один .jar файл.

Поэтому можно присвоить пакету jakarta-oro следующие auto provides:

Java(jakarta-oro)

Это выглядит довольно легко.

Теперь сложная часть - поиск Requires.

Для этого надо сначала пройтись по всем .jar файлам в /usr/share/java
и составить списки всех .class файлов находящихся в них.

for i in /usr/share/java/*.jar; do jar -tf $i | fgrep .class | cut -f
1 -d . > `basename $i .jar`; done

Получится список классов, которые содержатся в .jar-файле.

Теперь надо найти какие же из .jar-файлов, установленных в
/usr/share/java реально используются пакетом (auto requires).

Для проверки я взял пакет jakarta-oro-demo.

В нем скомпилированные классы находятся в незапакованном виде.
ls -1 /usr/share/java
ant
bcel.jar
excalibur-logkit.jar
geronimo-specs
jakarta-commons-collections.jar
jakarta-oro.jar
jakarta-regexp.jar
jakarta-servletapi4.jar
jaxp_parser_impl.jar
jaxp_transform_impl.jar
jdom.jar
jspapi5.jar
log4j.jar
serializer.jar
servletapi5.jar
servletapi.jar
velocity.jar
werken-xpath.jar
xalan-j.jar
xerces-j.jar
xml-commons-apis.jar
xml-commons-external.jar

После выполнения предыдущего скрипта у меня в текущей директории
получились вот такие вот файлы списков классов в каждом .jar

ls -1 .
bcel
excalibur-logkit
jakarta-commons-collections
jakarta-oro
jakarta-regexp
jakarta-servletapi4
jaxp_parser_impl
jaxp_transform_impl
jdom
jspapi5
log4j
serializer
servletapi
servletapi5
velocity
werken-xpath
xalan-j
xerces-j
xml-commons-apis
xml-commons-external

Я создал вот такой вот маленький скрипт-обертку для поиска requires:

cat ~/bin/find-java-requires
#!/bin/sh

JARLISTDIR=~/tmp/java #FIXME директория где лежат списки
for jarlist in $JARLISTDIR/*
do
        fgrep -qf "$jarlist" -- "$@" && echo "Java(`basename $jarlist`)"
done

Натравив его на .classes файлы из jakarta-oro-demo командой

find /usr/share/doc/jakarta-oro-2.0.8/ -name '*.class' -print0 | xargs
-r0 find-java-requires
я получил вывод
Java(jakarta-oro)

Вот какие автозависимости можно поставить пакету jakarta-oro-demo.

Теперь про пакеты с .jar файлами.

Возьмем например пакет velocity.

rpm -ql velocity | fgrep .jar
/usr/share/java/velocity.jar

Идея такая - распаковываем этот .jar файл в какую-нибудь временную
директорию, получаем список .class файлов и натравливаем на них
find-java-requires.

cat ~/bin/find-java-jar-requires
#!/bin/sh
OURDIR=`mktemp -dt`
cd "$OURDIR" && jar -xf "$1"
find "$OURDIR" -name '*.class' -print0 | xargs -r0 find-java-requires
rm -rf -- "$OURDIR"

Теперь смотрим результаты:
find-java-jar-requires /usr/share/java/velocity.jar
Java(excalibur-logkit)
Java(jakarta-commons-collections)
Java(jakarta-oro)
Java(jakarta-servletapi4)
Java(jdom)
Java(log4j)
Java(servletapi)
Java(servletapi5)
Java(velocity)
Java(werken-xpath)
Java(xml-commons-apis)
Java(xml-commons-external)
Вуаля!

Можно посмотреть еще остальные .jar файлы - например

find-java-jar-requires /usr/share/java/log4j.jar
Java(log4j)
Java(xml-commons-apis)
Java(xml-commons-external)

find-java-jar-requires /usr/share/java/bcel.jar
Java(bcel)
Java(jakarta-regexp)

find-java-jar-requires /usr/share/java/jakarta-servletapi4.jar
Java(jakarta-servletapi4)
Java(jspapi5)
Java(servletapi)
Java(servletapi5)

На первый взгляд все работает :)

Жду критики, комментариев и предложений по улучшению.


Подробная информация о списке рассылки Devel