Volgograd

Волгоград Linux User Group

Организована 23 ноября 2002 года

Проект заморожен Птн Июл 6 02:11:14 MSD 2012


Вход:  Пароль:  

ГраблеВодство/LearnAndTranslate/JPackagePolicy


Это старая версия ГраблеВодство/LearnAndTranslate/JPackagePolicy за 2007-07-01 19:06:14..

JPackage Java™ infrastructure design and packaging policy


Nicolas Mailhot
JPackage Project
Ville Skyttä
JPackage Project

$Id: jpackage-1.5-policy.xhtml,v 1.2 2005/09/17 07:06:26 david Exp $

Резюме
Этот документ содержит политику упаковки в соответсвии с JPackage cross-distribution RPM Java™ packaging project.



Оглавление документа




Почему?


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

Как следствие приложения были проверены только с версиями компонентов, с которыми они были связаны, вся Java-система страдает бесконечным дублированием одних и тех же модулей, объединение повторяющихся частей может быть кошмаром, так как они обязаны зависеть от тех же самых компонентов — только с различными и изощренно несовместимыми версиями#1. Любое обновление по безопасности или по совместимости должно быть выполнено для всех эти дублирующихся компонентов.

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

It is not surprising then that complex Java systems tend to fossilize very quickly, with the cost of maintaining dependencies current growing too high so fast people basically give up on it.
This situation is incompatible with your typical fast-evolving Linux platform. To attain its aim of user- and administrator-friendly rpm packaging of Java applications the JPackage Project had to evolve its own system infrastructure and strict packaging rules.

[1] Различные требования, раличные ошибки
[2] For example when the system kernel or C core changes Java assumptions.



Глава 1. Общие правила


Будь модульным

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

Be vendor and implementation agnostic

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

Be distribution agnostic

Пакеты должны работать на большинстве основных rpm-based дистрибутивах. Это означает следование стандартам, таких как Linux Standard Base, Filesystem Hierarchy Standard или freedesktop.org спецификациям

Прежде всего использование дистрибутивно-специфичных аппаратов#4 запрещено.

Note this is a pragmatic reading of the standards. Facilities not specified but commonly found are readily used by the project[5] and distribution-specific adaptations are tolerated provided they do not interfere with common usage or a generic version is also available.


[3] Основаные на лицензионных условиях, известные завершенности,
[4] Как Mandrake gprintf функция.
[5] Для примера rpm4 возможности, или Debian'ская alternatives(8) система...



Глава 2. Именование


Имя пакета


Пакеты должны быть называны общим именем их оригинально проекта в нижнем регистре. Когда пакет предоставляет расширение, которое было в какой-то момент заложено в Java стандарте, -ext (как external) суффикс должен быть добавлен, для различия между именем пакета и именем расширения. Both the JVMs including this extension and the standalone extension package shall then have the original name as a virtual Provides.


JVM должны носить имя java-standard_version-vendor. Оригинальное имя с сайта не должно использоваться в связи с широкой практикой разброса в именовании от вендора к вендроу и от версии к версии.

Jar-файл именование


  • Если пакет предоставляет только один jar, он должен иметь тоже имя что и пакет, с добавлением версии продукта.

  • Безверсионная символьная ссылка смотрящая на оригинальный файл тоже должна быть предоставлена (провайдена)

  • Если имя проекта и часто используемое jar имя отличаются, символьная ссылка на принятое имя должна так же предоставляться (провайдиться).

  • Если пакет предоставляет несколько jar'ов их принятые имена будут использованы

  • Если число предоставляемых jar'ом превышает два, или если они были предоставлены в виде монолитного jar'а, файлы должны быть помещены в поддиректорию с названием пакета (так же как и для одиночного jar'а).

  • Если проект предлагает выбор метода упаковки, между одни монолитным jar'ом или разбиением на несколько более мелких, упаковка с разбиением будет предпочтительнее.



Глава 3. Структура директорий


Основная структура директорий предоставляется пакетом jpackage-utils. Она состоит из:

%{_javadir}

/usr/share/java

%{_javadir} rpm макрос определяет главную jar-директорию. Исторически это была основная директория используемая 1.0 JPakage дистрибутивом, прежде чем packaging constraints forced a more complex system. Обычно она рассполагается в /usr/share/java.

/usr/share/java-ext

Из %{_javadir} мы получаем %{_javadir}-ext. Все jar-файлы и директории jar-файлов, которые зависят от конкретной версии Java-стандарта но не от JNI должны устанавливаться в %{_javadir}-ext.

/usr/share/java-x.y.z

Мы так же получаем %{_javadir}-x.y.z директории. Они содержат символьные ссылки на файлы или директории %{_javadir}-ext для все элементов, которые действительны для x.y.z версии Java-стандарта. С тех пор как реализация обычно действительна для ряда повторений Java-стандарта, файл или директория в %{_javadir}-ext будет содержать несколько символьных ссылок ссылающихся на нее. Так же следует отметить безверсионные символьные ссылки: для двух jar'ов названных foo13.jar и foo14.jar, foo.jar символьная ссылка будет указывать на foo13.jar в %{_javadir}-1.3.0 и %{_javadir}-1.3.1, и foo14.jar в %{_javadir}-1.4.0, %{_javadir}-1.4.1 и %{_javadir}-1.4.2.

К сожалению Java-стандарт как известно меняется сильно между minor версиями, так что мы должны учитывать полную версию и различия между %{_javadir}-1.4.0 и %{_javadir}-1.4.1.

Версионные особенности Java-стандарт при использовании в репозитарии

/usr/share/java-utils

Так же получаем %{_javadir}-utils. Используется для множества java-связанных скриптов и функций, включая главную библиотеку shell-функций java-functions.

%{_jnidir}: /usr/lib/java...


RPM макрос %{_jnidir} определяет главный JNI jar репозитарий. Так же как и %{_javadir} разветвляется на -ext и -x.y.z ветки. Он так же придерживается тех же правил что и %{_javadir}-ответвление, исключая, то что он содержит jar'ы, которые используют JNI.

%{_jnidir} обычно указывает на /usr/lib/java.

%{_jvmdir}

%{_libdir}/jvm: /usr/lib/jvm

RPM макрос %{_jvmdir} определяет корневую директорию в которую различные JVM-систему устанавливаются. Обычно это /usr/lib/jvm

%{_libdir}/jvm-exports: /usr/lib/jvm-exports

От %{_jvmdir} мы переходим к %{_jvmdir}-exports. Каждая поддиректория %{_jvmdir} должна иметь соответственную в %{_jvmdir}-exports. Они используются для регистрации Java-расширений связанных с SDK или RE символьными ссылками, указывающими внутрь JMV структуры в %{_jvmdir}.

Символьные ссылки должны указывать на фактический JVM jar-файл предоставляющий расширение (хотя это не жесткое требование для работы системы), должны присутствовать версионные и не версионные варианты и следовать общим правилам именования.

%{_libdir}/jvm-private: /usr/lib/jvm-private

%{_jvmdir}-private директория содержит «внутренние» JVM-файлы, но по каким-то причинам рассположенные не в стандартной JVM-директории. Скрипты не должны ссылаться на эти файлы. Внутри данной директории рассположенны версионные директории в соответствии с их назначением, содержащие файлы.

Как пример «внутренних» файлов можно рассмотреть файлы политики JCE (Java Cryptography Extension), те что идут вместе с различными 1.4.x JVM'ами jограничены в функциональности и производители поставляют неограниченные по функциональности файлы политек отдельно. Зачастую эти файлы часть какой-то версии Java-стандарта конкретного вендора (типа java-1.4.2-sun).

JCE файлы политек для Sun's J2SE 1.4.2


Различные версии jar'ов JCE-политик в дальнейшем управляются через систему альтернатив, использующую ссылку, которая указывает на соответствующий jar-файл в JVM jre/lib/security директории, с большим приоритетом на более функциональную версию чем ту что принадлежит JVM.

%{_sysconfdir}/java: /etc/java

%{_sysconfdir}/java содержит основные файлы конфигурация принадлежащие java-подсистеме, главным образом java.conf.

%{_javadocdir}

Это корень всех установленных javadoc документов. Его рассположение и предпологаемое использование обсуждается в данный момент.

Директории зависимые от приложения

  • Cобственные директории приложения должны рассполагаться в системе в соответствии с правилами Filesystem Hierarchy Standard

  • Если приложению необходимо свое файловое дерево, как в других операционных системах (а FHS требует, чтобы поддиректории были установленные в разные части системы), макрос %{_datadir}/appname должен быть использован как корневая-домашняя директория с символьными ссылками, указывающими на реальное рассположение поддиректорий в системе. Конечно лучше изменить приложение, чтобы оно понимало правильное разделение файлов и отменяло пляску с символьными ссылками.

FHS и централизованная домашняя директория приложения.

  • Велосипеды лучше не создавать. Если директория всегда имеет только один единственный подкаталог, избавтесь от него#6
  • Если приложение использует classpath-элементы, которые не являются jar-файлами, они должны быть установлены в собственную директорию приложения

zip, war и другие файлы акурхивов классов
Любой может столкнуться с другими типами архивов используемых в classpaths. Если прямой необходимости в использовании таких файлов нет, то следует конвертировать их в jar и использовать как обычно. Это своего рода правда о zip-файлах, которые были раньше широко расспространены, но со временем были признаны как устаревшие к использованию.

  • Если приложение содержит собственные jar-файлы которые будут всегда принадлежать одному пользователю, они должны быть установленны в собственные директории приложения.

  • Собственные jar-файлы
    Это предполагает что общий порядок не может быть использован для построения classpath-приложения, так что эта часть должна контролироваться самим приложением или его пакетом#7. Тем не менее, когда приложение может и будут читать его собственный jar-репозитарий, мы предлагаем средства для управления частей репозитария, которые совместно используются с другими приложениями.


    [6] те не создавайте единственный подкаталог для библиотеки в %{_datadir}/appname только потому что более сложные приложения делают это. Если он всегда будет один, используйте сразу %{_datadir}/appname.

    [7] Hardcoding classpath bits for example.



    Глава 4. Скрипты и выбор classpath при запуске


    Мы предполагаем что верные значения переменных окружения уже выставлены, по крайней мене $JAVA_HOME для выбора JVM в %{_jvmdir}, и в конечном счете $JAVACMD, $LD_ASSUME_KERNEL, $LANG, и $JAVA_COMPILER переменные.

    Исправить

    Текущая реализация данной политики не столь хороша как хотелось бы и тащит с собой кучу наследственного мусора. Нормальная реализация будет использовать значени переменных из ~/.apprc, с откатом в /etc/app.conf, хранением пользовательских переменных окружения в ~/.java и /etc/java/java.conf. Если $JAVA_HOME после этого будет не определена, то по умолчанию будет использовано значение /usr/lib/jvm/java.

    К сожалению, мы не делаем этого прямо сейчас.

    Основные правила разрешения

    Когда мы запрашиваем foo/bar-x.y, мы ищем foo/bar-x.y.jar jar-файл, затем foo/bar-x.y jar-директорию, в следющих местах:

    • %{_jvmdir}-exports/name Отображение JVM определено как $JAVA_HOME=%{_jvmdir}/name. Это JVM-специфичный репозитарий, в который вы вносим Java-расширения, принадлежащие ему.
    • %{_jnidir}-java_version Где java_version is the JVM standard Java compliance level as deduced from
    • %{_javadir}-java_version java-version specific non-JNI jar repository.
    • %{_jnidir} Основной JNI jar-репозитарий.
    • %{_javadir} Основной jar-репозитарий.

    Если мы ничего не находим, поиск повторяется для foo/bar.jar, foo/bar, foo.jar, и наконец foo каталог. Заметим, поиск выполняется для пары jar/директория, т.е. поддиректория расположенная в более конкретном репозитарии будет всегда иметь превосходство перед jar с таким же именем, но рассположенном в менее конкретном репозитарии.

    find-jar


    find-jar {объект}


    Команда find-jar проверяет рассположения указанного объекта. Возвращает имя jar-файл или директории, если результат выполнения команды положительный. Эта утилита предназначена исключительно для тестирования рассположения объекта и не должна использоваться в скриптах. Даже для определения однообъектных classpath'ов данная команда является предпочтительной, с тех пор как однообъектные поиски могут приводить к различным результатам, когда сводится к директории.



    build-classpath


    build-classpath {объект...}


    Команда build-classpath находит classpath, следуя основным правилам разрешения. Аргументами команды — является список объектов. Если объект разрешается в директорию, все jar-файлы этой директории будут включены в classpath.



    Рекомендованная практика посторения classpath, состоящей из достаточной и опциональной частей

    Построение classpath с достаточной и опциональной частью


    build-jar-repository


    build-jar-repository [[-s] | [--soft] | [--symbolic] | [-h] | [--hard] | [-c] | [--copy]] [[-p] | [--preserve-naming]] {директория} {объект...}


    Команда build-jar-repository создает структуру директорий симлинков на jar-файлы, по следующим правилам. Принимает в качестве аргументов имя директории и список объектов. После чего попытается создать набор символьных ссылок [foo][bar]xxx.jar в указанной директории для каждого запрошенного foo/bar объекта#8. Особая структура имен символьных ссылок делает возможным определить были ли они созданным имено этой командой, и является необходимым условием для использования rebuild-jar-repository. Можно указать, какого типа будут создаваемые объекты: символьной ссылкой, жесткой или копией файла. По умолчанию — символьная ссылка, другой тип должен быть использован только для сильно поврежденного ПО.

    Инкрементное использование
    build-jar-repository может быть свободно использован для одной и той же директории. Предыдущие симлинки не будут удалены. Удаление символьных ссылок в директории, производится только пользователем, утилита этого не делает.

    Задание имен, для безопасного перемещения
    Если вы хотите расспространить директория с jar копиями или ссылками на них, вы можете использовать ключ --preserve-naming. При его использовании, build-jar-repository будет создавать файлы с именами наиболее близкими к оригинальным. Заметим, что это приведет к будущим проблемам при обновления этого репозитария. Не используйте данный ключ, пока вы точно не будете уверены, что вы делаете.

    --preserve-naming включает в себя --copy, пока не определенно обратного.



    rebuild-jar-repository


    rebuild-jar-repository [[-s] | [--soft] | [--symbolic] | [-h] | [--hard] | [-c] | [--copy]] {директория}


    Команда rebuild-jar-repository обновляет jar-репозитарий, созданный build-jar-repository. Аргументом команды является имя директории, и предназначена для исправления символьных ссылок после изменения $JAVA_HOME, для совместимости с новым JVM. Опции для типа создаваемых объектов такие же что и у build-jar-repository.

    Смешанное использование
    Специфичные имена символьных ссылок, которые создаются build-jar-repository и rebuild-jar-repository позволяют смешивать автоматические ссылки, созданные в ручную и обычные файлы в директориях, обрабатываемых этими утилитами. Скрипты меняют только имена собственных ссылок



    Невозможность разрешения объекта...
    В отличии от build-jar-repository, rebuild-jar-repository будет создавать символьные ссылки. Это сделано для предотвращения потери объектов при сломанной java-подсистеме.#9 Созданная символьная ссылка указывает в «никуда» и всегда должна быть «поломанной».


    [8] Единичный объект может быть разрешен в директорию с большим числом jar-файлов.

    [9] Если устранить проблемы: установка нужных jar'ов или выбор более полной версии JVM, то rebuild-jar-repository отработает нормально, как-будто ничего и не случалось.