[devel] Java: no magic wand

Igor Vlasenko =?iso-8859-1?q?vlasenko_=CE=C1_imath=2Ekiev=2Eua?=
Чт Янв 10 23:41:06 MSK 2008


Java: no magic wand.
--------------------

Уважаемые коллеги, хотел бы поделиться своими мыслями 
по поводу развития java - подрепозитория Сизифа.

Некоторые вопросы уже обсуждались в беседах с 
Виталием Липатовым и Денисом Смирновым, в частности, 
был вопрос, когда же в java-пакетах появится 
автоопределение зависимостей.

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

Почему так?

Хотел бы ответить на этот вопрос развернуто.

Напомню, зачем нужно автоопределение зависимостей 
и как оно работает.

IMHO, автоопределение зависимостей нужно, чтобы пакеты 
работали "из коробки". Программа с неудоволетворенными 
зависимостями может падать со сложной диагностикой, 
и не всякий пользователь разберется, в чем дело.

Работает оно, потому что в языке (perl,python,ruby...)
или стандартно в системе (C,C++,...) есть

1) стандартные названия библиотек 
[никому из нас и в голову не придет собирать libz как 
libaltz и пытаться продавливать в апстримы патчи
вида s/-lz/-laltz/ либо паковать Pod::Parser как 
Documents::Pod::Parser], не зависящие от названия пакета
(zlib или libz или libaltz, perl или perl-Pod или 
perl-PodDocumentUtils)

2) стандартная (мета)информация о зависимостях
(выполнена ли она в виде директивы import в питоне
либо находится в заголовке ELF binary file)

3) стандартные пути поиска (/usr/lib, %perl_vendorsdir,..)

4) стандартный загрузчик, который используя 2) рекурсивно
ищет 1) в 3).
В этом случае для успешной компоновки программы 
с библиотеками есть только одно препятствие --
отсутствие в системе нужных библиотек и автоопределение 
зависимостей эту проблему успешно решает, без труда 
со стороны майнтайнера, как волшебная палочка.

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

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

1') нет метаинформации о компоновочных зависимостях;

2') нет стандартных путей поиска;

3') нет стандартных названий библиотек.

соответственно нет и 
4') стандартного рекурсивного компоновщика/загрузчика, 
который бы использовал 1-3).

(у gcj, правда, есть свой мопед, связанный с компиляцией
в нативный код; но это уже не java.)

Что в этой ситуации даст корректное автоопределение 
зависимостей?

Поясню на примере. Пусть у нас есть редактор .xyz файлов,
jxyzedit. Его запуск неразрывно связан с компоновкой.
Чтобы его запустить, нужно в /usr/bin/jxyzedit 
(шелл - скрипте запуска) написать что-то вроде 
java -classpath $(build-classpath commons-codec):\
$(build-classpath jxyzedit) org.jxyzedit.GUI.Main
либо, раскрывая,
java -classpath /usr/share/java/commons-codec.jar\
:/usr/share/java/jxyzedit.jar org.jxyzedit.GUI.Main

Пример 1.
---------
Пусть идеальный автоопределитель зависимостей, 
изучая jxyzedit.jar, вывел зависимость jxyzedit 
на jakarta-commons-codec (содержащий commons-codec.jar).

Пусть теперь вышла новая версия commons-codec,
у которой внутренняя кухня теперь использует commons-primitives
(нечто подобное, кстати, уже было).

Пусть идеальный автоопределитель зависимостей, 
изучая commons-codec.jar, вывел зависимость нового
jakarta-commons-codec на jakarta-commons-primitives. 
(содержащий commons-primitives.jar).

При обновлении jakarta-commons-codec доустанавливается
jakarta-commons-primitives, но jxyzedit благополучно
падает, поскольку надо руками править запуск jxyzedit
и добавлять туда commons-primitives.jar.

Пример 2.
---------
Пусть вышла новая версия jxyzedit, требующая для работы
commons-compress.jar из jakarta-commons-compress.

Идеальный автоопределитель зависимостей, изучая 
jxyzedit.jar, добавил зависимость jxyzedit на jakarta-\
commons-compress (содержащий commons-compress.jar).

Но скрипты для запуска jxyzedit писал майнтайнер,
поскольку сам апстрим запускает свой jxyzedit в таком
оффтопике, что не к ночи в этой рассылке будь помянуто.
Он невнимательно провел сборку и не поправил запуск jxyzedit.

Теперь при установке jxyzedit устанавливается
jakarta-commons-compress, но jxyzedit благополучно
падает, поскольку надо руками править запуск jxyzedit
и добавлять туда commons-compress.jar.

Таким образом, если нет 1)-4), то 
от идеального автоопределителя зависимостей 
пользователю ни холодно, ни жарко. 
No magic wand.

======================================================
Небольшое отступление.
----------------------

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

Дамир, а потом и Алексей, предлагали реализации 
автоопределителя для java. как понимаю,
у этих подходов проблемы с зависимостями на интерфейсы.

Как я говорил, без  1)-4) идеальный автоопределитель
почти бесполезен. И, как показывает горький опыт,
некорректный автоопределитель существенно вреден,
поскольку иногда проставляет некорректные зависимости.
на борьбу с которыми тратится много сил.

Не хочется иметь ситуацию, когда при установке tomcat
вытягивается jboss, а заодно и jetty (или наоборот).

Примером полезного автоопределителя, на борьбу с которым
тратится много сил, является symlinks.req. Его 
полезным побочным эффектом является обнаружение линковочных
зависимостей для java специального вида, но сейчас у него 
возникают проблемы с разными библиотеками, реализующими 
один и тот же интерфейс. Но и проблемы полезны, поскольку 
тем самым он указывет на некоторые внутренние проблемы 
репозитария (там, где сам не ошибается). Вот как раз в 
последней сборке jetty5 всплыли проблемы с symlinks.req. 
Разберусь - доложу в bugzilla.

====================================================

Вывод.
------
A. без  1)-4) идеальный автоопределитель зависимостей 
для java почти бесполезен.

B. Сначала нужно заботиться об 1)-4).

C. Ошибки в реализации велосипедов с колесами 1)-4)
и рулем в виде автоопределителя зависимостей будут
больно бить и по Сизифу (придется каждый раз 
пересобирать заново), и по пользователям.

поэтому

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

-- 

Dr. Igor Vlasenko
--------------------
Topology Department
Institute of Math
Kiev, Ukraine




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