Java/JPackagePolicyTranslation: различия между версиями
(примечания) |
Manowar (обсуждение | вклад) м ("файлах" -> "файлов") |
||
(не показано 8 промежуточных версий 4 участников) | |||
Строка 1: | Строка 1: | ||
== JPackage Java<sup>TM</sup> 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 $ | |||
=== Резюме === | |||
Этот документ содержит политику упаковки в соответствии с [http://www.jpackage.org JPackage] cross-distribution RPM Java? packaging project. | Этот документ содержит политику упаковки в соответствии с [http://www.jpackage.org JPackage] cross-distribution RPM Java? packaging project. | ||
=== Почему? === | === Почему? === | ||
Нормальная упаковка Java всегда являлась сложной задачей. Нехватка стандартов относительно расположения файлов в системе, в купе с общими условиями лицензирования, которые позволяли лишь свободное распространение ключевых компонентов только как часть единого целого, привели к систематическому выпуску самодостаточных приложений со встроенными копиями внешних компонентов. | Нормальная упаковка Java всегда являлась сложной задачей. Нехватка стандартов относительно расположения файлов в системе, в купе с общими условиями лицензирования, которые позволяли лишь свободное распространение ключевых компонентов только как часть единого целого, привели к систематическому выпуску самодостаточных приложений со встроенными копиями внешних компонентов. | ||
Как следствие, приложения были проверены только с версиями компонентов, с которыми они были связаны. Вся Java-система страдает бесконечным дублированием одних и тех же модулей, объединение повторяющихся частей может быть кошмаром, так как они обязаны зависеть от тех же самых компонентов -- только с различными и изощренно несовместимыми версиями<ref>Различные требования, различные ошибки</ref>. Любое обновление по безопасности или по совместимости должно быть выполнено для всех | Как следствие, приложения были проверены только с версиями компонентов, с которыми они были связаны. Вся Java-система страдает бесконечным дублированием одних и тех же модулей, объединение повторяющихся частей может быть кошмаром, так как они обязаны зависеть от тех же самых компонентов -- только с различными и изощренно несовместимыми версиями<ref>Различные требования, различные ошибки</ref>. Любое обновление по безопасности или по совместимости должно быть выполнено для всех этих дублирующихся компонентов. | ||
Эта проблема получена в результате текущей практики вложения расширений прямо в JVM. По прошествии некоторого времени, компонент, который мог нормально быть встроен в приложение, неожиданно начинает конфликтовать с частью JVM и приводить к коварным падениям и ошибкам. | Эта проблема получена в результате текущей практики вложения расширений прямо в JVM. По прошествии некоторого времени, компонент, который мог нормально быть встроен в приложение, неожиданно начинает конфликтовать с частью JVM и приводить к коварным падениям и ошибкам. | ||
Это не удивительно, что сложные Java системы имеют тенденцию костенеть очень быстро. И приводить к быстрому росту стоимости обслуживания, что в свою очередь приводит к падению интереса к поддержанию таких систем в рабочем состоянии. И в конечном итоге люди бросают этим заниматься. | Это не удивительно, что сложные Java системы имеют тенденцию костенеть очень быстро. И приводить к быстрому росту стоимости обслуживания, что в свою очередь приводит к падению интереса к поддержанию таких систем в рабочем состоянии. И в конечном итоге люди бросают этим заниматься. | ||
Данная ситуация не совместима с типичной быстро развивающейся Linux-системой. Чтобы достигнуть своей цели, создания дружественных для пользователей и администраторов методов rpm упаковки Java приложений, JPackage Project должен развить свою системную инфраструктуру и строгие правила упаковки. | Данная ситуация не совместима с типичной быстро развивающейся Linux-системой. Чтобы достигнуть своей цели, создания дружественных для пользователей и администраторов методов rpm упаковки Java приложений, JPackage Project должен развить свою системную инфраструктуру и строгие правила упаковки. | ||
=== Глава 1. Общие правила === | === Глава 1. Общие правила === | ||
Строка 51: | Строка 38: | ||
Прежде всего запрещено использование дистрибутивно-специфичных особенностей<ref>Как [http://www.mandrakelinux.com/ Mandrake]'овская gprintf функция.</ref> | Прежде всего запрещено использование дистрибутивно-специфичных особенностей<ref>Как [http://www.mandrakelinux.com/ Mandrake]'овская gprintf функция.</ref> | ||
''Отметим, что это - прагматическое чтение стандартов. Средства обслуживания не определены, но в основном находятся в состоянии готовности для использования в проекте<ref>Для примера RPM 4 возможности, или [http://debian.org Debian]'ская система alternatives(8)...</ref>, дистрибутивно-специфичные адаптации допускаются при условии их не вмешательства в общее использование.'' | |||
=== Глава 2. Назначение имен === | === Глава 2. Назначение имен === | ||
Строка 60: | Строка 44: | ||
==== Имя пакета ==== | ==== Имя пакета ==== | ||
Пакеты должны быть названы общим именем их оригинального проекта в нижнем регистре. Когда пакет предоставляет расширение, которое было в какой-то момент заложено в Java стандарте, ''-ext'' (как external) суффикс должен быть добавлен, для различия между именем пакета и именем расширения. И JVM, которое включает данное расширение, и автономный пакет расширения, должны иметь оригинальное название как | Пакеты должны быть названы общим именем их оригинального проекта в нижнем регистре. Когда пакет предоставляет расширение, которое было в какой-то момент заложено в Java стандарте, ''-ext'' (как external) суффикс должен быть добавлен, для различия между именем пакета и именем расширения. И JVM, которое включает данное расширение, и автономный пакет расширения, должны иметь оригинальное название как ''virtual Provides''. | ||
JVM должны носить имя -- <tt>java-standard_version-vendor</tt>. Оригинальное название с сайта не должно использоваться в связи с широкой практикой разброса в именовании от вендора к вендроу и от версии к версии. | JVM должны носить имя -- <tt>java-standard_version-vendor</tt>. Оригинальное название с сайта не должно использоваться в связи с широкой практикой разброса в именовании от вендора к вендроу и от версии к версии. | ||
==== Название Jar-файлов ==== | ==== Название Jar-файлов ==== | ||
* Если пакет предоставляет только один jar, он должен иметь тоже название что и пакет, с добавлением версии продукта. | * Если пакет предоставляет только один jar, он должен иметь тоже название что и пакет, с добавлением версии продукта. | ||
jaf-1.0.2.jar | |||
* Безверсионная символьная ссылка, смотрящая на оригинальный файл тоже должна быть предоставлена (провайдена) | * Безверсионная символьная ссылка, смотрящая на оригинальный файл тоже должна быть предоставлена (провайдена) | ||
jaf-1.0.2.jar | |||
jaf.jar -> jaf-1.0.2.jar | jaf.jar -> jaf-1.0.2.jar | ||
* Если название проекта и часто используемое jar-имя отличаются, символьная ссылка на принятое имя должна так же быть предоставлена (провайдиться). | * Если название проекта и часто используемое jar-имя отличаются, символьная ссылка на принятое имя должна так же быть предоставлена (провайдиться). | ||
jaf-1.0.2.jar | |||
jaf.jar -> jaf-1.0.2.jar | jaf.jar -> jaf-1.0.2.jar | ||
activation.jar -> jaf-1.0.2.jar | activation.jar -> jaf-1.0.2.jar | ||
* Если пакет состоит из нескольких jar'ов, их обычные названия также будут использоваться. | * Если пакет состоит из нескольких jar'ов, их обычные названия также будут использоваться. | ||
ant-1.5.3.jar | |||
ant.jar -> ant-1.5.3.jar | ant.jar -> ant-1.5.3.jar | ||
ant-optional-1.5.3.jar | ant-optional-1.5.3.jar | ||
ant-optional.jar -> ant-optional-1.5.3.jar | ant-optional.jar -> ant-optional-1.5.3.jar | ||
* Если число jar'ов превышает два, или если они были предоставлены в виде монолитного jar'а, файлы должны быть помещены в поддиректорию с названием пакета (так же как и для одиночного jar'а). | * Если число jar'ов превышает два, или если они были предоставлены в виде монолитного jar'а, файлы должны быть помещены в поддиректорию с названием пакета (так же как и для одиночного jar'а). | ||
javamail | |||
javamail/imap-1.3.jar | javamail/imap-1.3.jar | ||
javamail/imap.jar -> imap-1.3.jar | javamail/imap.jar -> imap-1.3.jar | ||
javamail/mailapi-1.3.jar | javamail/mailapi-1.3.jar | ||
javamail/mailapi.jar -> mailapi-1.3.jar | javamail/mailapi.jar -> mailapi-1.3.jar | ||
javamail/pop3-1.3.jar | javamail/pop3-1.3.jar | ||
javamail/pop3.jar -> pop3-1.3.jar | javamail/pop3.jar -> pop3-1.3.jar | ||
javamail/smtp-1.3.jar | javamail/smtp-1.3.jar | ||
javamail/smtp.jar -> smtp-1.3.jar | javamail/smtp.jar -> smtp-1.3.jar | ||
* Если проект предлагает выбор метода упаковки, между одним монолитным jar'ом или разбиением на несколько более мелких, упаковка с разбиением будет предпочтительнее. | |||
=== Глава 3. Структура директорий === | === Глава 3. Структура директорий === | ||
Строка 108: | Строка 88: | ||
===== /usr/share/java ===== | ===== /usr/share/java ===== | ||
RPM макрос <tt>%{_javadir}</tt> задает главный jar- | RPM макрос <tt>%{_javadir}</tt> задает главный jar-репозиторий. Исторически это была единственная директория, используемая 1.0 JPakage, прежде чем упаковочные ограничения привели к более сложной системе. Он обычно раскрывается в <tt>/usr/share/java</tt>. | ||
Все jar-файлы и директории с jar-файлами, которые не зависят от конретной версии Java-стандарта или JNI должны быть установлены в <tt>%{_javadir}</tt>. | Все jar-файлы и директории с jar-файлами, которые не зависят от конретной версии Java-стандарта или JNI должны быть установлены в <tt>%{_javadir}</tt>. | ||
===== /usr/share/java-ext ===== | ===== /usr/share/java-ext ===== | ||
От <tt>%{_javadir}</tt> мы получаем <tt>%{_javadir}-ext</tt>. Все jar-файлы и директории jar-файлов, которые зависят от конкретной версии Java-стандарта, но не от JNI должны быть установлены в <tt>%{_javadir}-ext</tt>. | От <tt>%{_javadir}</tt> мы получаем <tt>%{_javadir}-ext</tt>. Все jar-файлы и директории jar-файлов, которые зависят от конкретной версии Java-стандарта, но не от JNI, должны быть установлены в <tt>%{_javadir}-ext</tt>. | ||
===== /usr/share/java-x.y.z ===== | ===== /usr/share/java-x.y.z ===== | ||
Директории <tt>%{_javadir}-x.y.z</tt> содержат символьные ссылки на файлы или директории для всех элементов <tt>%{_javadir}-ext</tt>, которые действительны для x.y.z версии Java-стандарта. С тех пор как реализация обычно действительна для ряда повторений Java-стандартов, файл или директория в <tt>%{_javadir}-ext</tt> будет содержать несколько символьных ссылок ссылающихся на нее. Так же следует отметить безверсионные символьные ссылки: для двух jar'ов названных <tt>foo13.jar</tt> и <tt>foo14.jar</tt>, <tt>foo.jar</tt> символьная ссылка будет указывать на <tt>foo13.jar</tt> в <tt>%{_javadir}-1.3.0</tt> и <tt>%{_javadir}-1.3.1</tt>, и <tt>foo14.jar</tt> в <tt>%{_javadir}-1.4.0</tt>, <tt>%{_javadir}-1.4.1</tt> и <tt>%{_javadir}-1.4.2</tt>. | Директории <tt>%{_javadir}-x.y.z</tt> содержат символьные ссылки на файлы или директории для всех элементов <tt>%{_javadir}-ext</tt>, которые действительны для x.y.z версии Java-стандарта. С тех пор как реализация обычно действительна для ряда повторений Java-стандартов, файл или директория в <tt>%{_javadir}-ext</tt> будет содержать несколько символьных ссылок ссылающихся на нее. Так же следует отметить безверсионные символьные ссылки: для двух jar'ов названных <tt>foo13.jar</tt> и <tt>foo14.jar</tt>, <tt>foo.jar</tt> символьная ссылка будет указывать на <tt>foo13.jar</tt> в <tt>%{_javadir}-1.3.0</tt> и <tt>%{_javadir}-1.3.1</tt>, и <tt>foo14.jar</tt> в <tt>%{_javadir}-1.4.0</tt>, <tt>%{_javadir}-1.4.1</tt> и <tt>%{_javadir}-1.4.2</tt>. | ||
Строка 120: | Строка 100: | ||
К сожалению, Java-стандарт как известно меняется довольно сильно между младшими версиями, поэтому мы должны учитывать полную версию и различия между <tt>%{_javadir}-1.4.0</tt> и <tt>%{_javadir}-1.4.1</tt>. | К сожалению, Java-стандарт как известно меняется довольно сильно между младшими версиями, поэтому мы должны учитывать полную версию и различия между <tt>%{_javadir}-1.4.0</tt> и <tt>%{_javadir}-1.4.1</tt>. | ||
Версионные особенности Java-стандарт при использовании в репозитории | |||
/usr/share/java-ext/jsse | |||
/usr/share/java-ext/jsse | /usr/share/java-ext/jsse/jcert-1.0.3.01.jar | ||
/usr/share/java-ext/jsse/jcert-1.0.3.01.jar | /usr/share/java-ext/jsse/jcert.jar -> jcert-1.0.3.01.jar | ||
/usr/share/java-ext/jsse/jcert.jar -> jcert-1.0.3.01.jar | /usr/share/java-ext/jsse/jnet-1.0.3.01.jar | ||
/usr/share/java-ext/jsse/jnet-1.0.3.01.jar | /usr/share/java-ext/jsse/jnet.jar -> jnet-1.0.3.01.jar | ||
/usr/share/java-ext/jsse/jnet.jar -> jnet-1.0.3.01.jar | /usr/share/java-ext/jsse/jsse-1.0.3.01.jar | ||
/usr/share/java-ext/jsse/jsse-1.0.3.01.jar | /usr/share/java-ext/jsse/jsse.jar -> jsse-1.0.3.01.jar | ||
/usr/share/java-ext/jsse/jsse.jar -> jsse-1.0.3.01.jar | /usr/share/java-1.3.0/jsse -> /usr/share/java-ext/jsse | ||
/usr/share/java-1.3.0/jsse -> /usr/share/java-ext/jsse | /usr/share/java-1.3.1/jsse -> /usr/share/java-ext/jsse</pre> | ||
/usr/share/java-1.3.1/jsse -> /usr/share/java-ext/jsse</pre> | |||
===== /usr/share/java-utils ===== | ===== /usr/share/java-utils ===== | ||
Строка 136: | Строка 115: | ||
==== %{_jnidir}: /usr/lib/java... ==== | ==== %{_jnidir}: /usr/lib/java... ==== | ||
RPM макрос <tt>%{_jnidir}</tt> определяет главный JNI jar- | RPM макрос <tt>%{_jnidir}</tt> определяет главный JNI jar-репозиторий. Так же как и <tt>%{_javadir}</tt> разветвляется на ветки <tt>-ext</tt> и <tt>-x.y.z</tt> . Придерживается тех же правил что и <tt>%{_javadir}-ответвление</tt>, исключая, то что он содержит jar'ы, которые используют JNI. | ||
<tt>%{_jnidir}</tt> обычно указывает на /usr/lib/java. | <tt>%{_jnidir}</tt> обычно указывает на /usr/lib/java. | ||
Строка 142: | Строка 121: | ||
==== %{_jvmdir} ==== | ==== %{_jvmdir} ==== | ||
===== %{_libdir}/jvm: /usr/lib/jvm ===== | ===== %{_libdir}/jvm: /usr/lib/jvm ===== | ||
RPM макрос <tt>%{_jvmdir}</tt> определяет корневую директорию, в которую устанавливаются различные JVM-системы. Обычно это <tt>/usr/lib/jvm</tt> | RPM макрос <tt>%{_jvmdir}</tt> определяет корневую директорию, в которую устанавливаются различные JVM-системы. Обычно это <tt>/usr/lib/jvm</tt>. | ||
===== %{_libdir}/jvm-exports: /usr/lib/jvm-exports ===== | ===== %{_libdir}/jvm-exports: /usr/lib/jvm-exports ===== | ||
От <tt>%{_jvmdir}</tt> мы переходим к <tt>%{_jvmdir}-exports</tt>. Каждая поддиректория <tt>%{_jvmdir}</tt> должна иметь соответствующую в <tt>%{_jvmdir}-exports</tt>. Они используются для регистрации Java-расширений связанных с SDK или RE символьными ссылками, указывающими внутрь JMV структуры в <tt>%{_jvmdir}</tt>. | От <tt>%{_jvmdir}</tt> мы переходим к <tt>%{_jvmdir}-exports</tt>. Каждая поддиректория <tt>%{_jvmdir}</tt> должна иметь соответствующую в <tt>%{_jvmdir}-exports</tt>. Они используются для регистрации Java-расширений связанных с SDK или RE символьными ссылками, указывающими внутрь JMV структуры в <tt>%{_jvmdir}</tt>. | ||
Строка 156: | Строка 133: | ||
Как пример "внутренних" файлов можно рассмотреть файлы политики JCE (Java Cryptography Extension), те что идут вместе с различными 1.4.x JVM'ами ограничены в функциональности и производители поставляют неограниченные по функциональности файлы политик отдельно. Зачастую эти файлы -- часть какой-то версии Java-стандарта конкретного вендора (типа java-1.4.2-sun). | Как пример "внутренних" файлов можно рассмотреть файлы политики JCE (Java Cryptography Extension), те что идут вместе с различными 1.4.x JVM'ами ограничены в функциональности и производители поставляют неограниченные по функциональности файлы политик отдельно. Зачастую эти файлы -- часть какой-то версии Java-стандарта конкретного вендора (типа java-1.4.2-sun). | ||
JCE файлы политик для Sun's J2SE 1.4.2: | |||
/usr/lib/jvm-private/java-1.4.2-sun | |||
/usr/lib/jvm-private/java-1.4.2-sun | /usr/lib/jvm-private/java-1.4.2-sun/jce | ||
/usr/lib/jvm-private/java-1.4.2-sun/jce | /usr/lib/jvm-private/java-1.4.2-sun/jce/vanilla | ||
/usr/lib/jvm-private/java-1.4.2-sun/jce/vanilla | /usr/lib/jvm-private/java-1.4.2-sun/jce/vanilla/US_export_policy.jar | ||
/usr/lib/jvm-private/java-1.4.2-sun/jce/vanilla/US_export_policy.jar | /usr/lib/jvm-private/java-1.4.2-sun/jce/vanilla/local_policy.jar | ||
/usr/lib/jvm-private/java-1.4.2-sun/jce/vanilla/local_policy.jar | /usr/lib/jvm-private/java-1.4.2-sun/jce/unlimited | ||
/usr/lib/jvm-private/java-1.4.2-sun/jce/unlimited | /usr/lib/jvm-private/java-1.4.2-sun/jce/unlimited/US_export_policy.jar | ||
/usr/lib/jvm-private/java-1.4.2-sun/jce/unlimited/US_export_policy.jar | /usr/lib/jvm-private/java-1.4.2-sun/jce/unlimited/local_policy.jar | ||
/usr/lib/jvm-private/java-1.4.2-sun/jce/unlimited/local_policy.jar | |||
Различные версии jar'ов JCE-политик в дальнейшем управляются через систему альтернатив, использующую ссылку, которая указывает на соответствующий jar-файл в JVM <tt>jre/lib/security</tt> директории, с большим приоритетом на более функциональную версию чем та что принадлежит JVM. | Различные версии jar'ов JCE-политик в дальнейшем управляются через систему альтернатив, использующую ссылку, которая указывает на соответствующий jar-файл в JVM <tt>jre/lib/security</tt> директории, с большим приоритетом на более функциональную версию чем та что принадлежит JVM. | ||
==== %{_sysconfdir}/java: /etc/java ==== | ==== %{_sysconfdir}/java: /etc/java ==== | ||
<tt>%{_sysconfdir}/java</tt> содержит основные файлы | <tt>%{_sysconfdir}/java</tt> содержит основные файлы конфигурации, принадлежащие java-подсистеме, главным образом java.conf. | ||
==== %{_javadocdir} ==== | ==== %{_javadocdir} ==== | ||
Строка 179: | Строка 154: | ||
* Собственные директории приложения должны располагаться в системе в соответствии с правилами [http://www.pathname.com/fhs/ Filesystem Hierarchy Standard] | * Собственные директории приложения должны располагаться в системе в соответствии с правилами [http://www.pathname.com/fhs/ Filesystem Hierarchy Standard] | ||
* Если приложению необходимо свое файловое дерево, как в других операционных системах (а FHS требует, чтобы поддиректории были установленные в разные части системы), макрос <tt>%{_datadir}/appname</tt> должен быть использован как корневая-домашняя директория с символьными ссылками, указывающими на реальное расположение поддиректорий в системе. Конечно лучше изменить приложение, чтобы оно понимало правильное разделение файлов и отменяло пляску с символьными ссылками. | * Если приложению необходимо свое файловое дерево, как в других операционных системах (а FHS требует, чтобы поддиректории были установленные в разные части системы), макрос <tt>%{_datadir}/appname</tt> должен быть использован как корневая-домашняя директория с символьными ссылками, указывающими на реальное расположение поддиректорий в системе. Конечно лучше изменить приложение, чтобы оно понимало правильное разделение файлов и отменяло пляску с символьными ссылками. | ||
FHS и централизованная домашняя директория приложения: | |||
/usr/share/tomcat4 | |||
/usr/share/tomcat4/bin | |||
/usr/share/tomcat4/common -> /var/lib/tomcat4/common | |||
/usr/share/tomcat4/conf -> /etc/tomcat4 | |||
/usr/share/tomcat4/logs -> /var/log/tomcat4 | |||
/usr/share/tomcat4/server -> /var/lib/tomcat4/server | |||
/usr/share/tomcat4/shared -> /var/lib/tomcat4/shared | |||
/usr/share/tomcat4/temp -> /var/cache/tomcat4/temp | |||
/usr/share/tomcat4/webapps ->/var/lib/tomcat4/webapps | |||
/usr/share/tomcat4/work -> /var/cache/tomcat4/work | |||
* Велосипеды лучше не создавать. Если директория всегда имеет только один единственный подкаталог, избавьтесь от него<ref>те не создавайте единственный подкаталог для библиотеки в <tt>%{_datadir}/appname</tt>, только потому что более сложные приложения делают это. Если он всегда будет один, используйте сразу <tt>%{_datadir}/appname</tt></ref> | |||
* Если приложение использует classpath-компоненты, которые не являются jar-файлами, они должны быть установлены в собственную директорию приложения | * Если приложение использует classpath-компоненты, которые не являются jar-файлами, они должны быть установлены в собственную директорию приложения | ||
==== zip, war и другие файлы архивов классов ==== | |||
Любой может столкнуться с другими типами архивов используемых в classpaths. Если прямой необходимости в использовании таких файлов нет, то следует конвертировать их в jar. Это особенно важно для zip-файлов, которые были одно время в широком использовании, но в последствии вышли из употребления. | |||
* Если приложение состоит из собственных jar-файлов, то это всегда будет только одного пользователя, и они могут быть установлены в собственные директории приложения. | * Если приложение состоит из собственных jar-файлов, то это всегда будет только одного пользователя, и они могут быть установлены в собственные директории приложения. | ||
==== Собственные jar-файлы ==== | |||
Это предполагает, что стандартные правила, не могут быть использованы для построения classpath-приложения, таким образом эта часть должна быть обработана самим приложением или мантейнером пакета<ref>Hardcoding classpath bits for example</ref>. Тем не менее, когда приложение может и будут читать собственный jar-репозиторий, мы действительно обеспечиваем средствами для управления частями репозитория, которые используются совместно с другими приложениями. | |||
=== Глава 4. Скрипты и выбор classpath при запуске === | === Глава 4. Скрипты и выбор classpath при запуске === | ||
Строка 213: | Строка 184: | ||
Мы предполагаем что верные значения переменных окружения уже выставлены, по крайней мене <tt>$JAVA_HOME</tt> для выбора JVM в <tt>%{_jvmdir}</tt>, и в конечном счете <tt>$JAVACMD</tt>, <tt>$LD_ASSUME_KERNEL</tt>, <tt>$LANG</tt>, и <tt>$JAVA_COMPILER</tt> переменные. | Мы предполагаем что верные значения переменных окружения уже выставлены, по крайней мене <tt>$JAVA_HOME</tt> для выбора JVM в <tt>%{_jvmdir}</tt>, и в конечном счете <tt>$JAVACMD</tt>, <tt>$LD_ASSUME_KERNEL</tt>, <tt>$LANG</tt>, и <tt>$JAVA_COMPILER</tt> переменные. | ||
'''''FIXME: Исправить''''' | |||
Текущая реализация данной политики не столь хороша как хотелось бы и тащит с собой кучу наследственного мусора. Нормальная реализация будет использовать значения переменных из <tt>/.apprc</tt>, с откатом в <tt>/etc/app.conf</tt>, хранением пользовательских переменных окружения в <tt>/.java</tt> и <tt>/etc/java/java.conf</tt>. Если <tt>$JAVA_HOME</tt> после этого будет не определена, то по умолчанию будет использовано значение <tt>/usr/lib/jvm/java</tt>. | |||
К сожалению, мы не делаем этого прямо сейчас. | К сожалению, мы не делаем этого прямо сейчас. | ||
==== Основные правила разрешения ==== | ==== Основные правила разрешения ==== | ||
Когда мы запрашиваем <tt>foo/bar-x.y</tt>, мы ищем <tt>foo/bar-x.y.jar</tt> jar-файл, затем <tt>foo/bar-x.y</tt> jar-директорию, в следующих местах: | Когда мы запрашиваем <tt>foo/bar-x.y</tt>, мы ищем <tt>foo/bar-x.y.jar</tt> jar-файл, затем <tt>foo/bar-x.y</tt> jar-директорию, в следующих местах: | ||
* <tt>%{_jvmdir}-exports/name</tt> Отображение JVM определено как <tt>$JAVA_HOME=%{_jvmdir}/name</tt>. Это JVM-специфичный | * <tt>%{_jvmdir}-exports/name</tt> Отображение JVM определено как <tt>$JAVA_HOME=%{_jvmdir}/name</tt>. Это JVM-специфичный репозиторий, в который вы вносим Java-расширения, принадлежащие ему. | ||
* <tt>%{_jnidir}-java_version</tt> | * <tt>%{_jnidir}-java_version</tt> ''Где <tt>java_version</tt> является JVM стандартным Java уровнем согласия как видно из'' | ||
[bob@sys dir]$ $JAVACMD -version | |||
* <tt>%{_javadir}-java_version</tt> java-version specific non-JNI jar repository. | * <tt>%{_javadir}-java_version</tt> java-version specific non-JNI jar repository. | ||
* <tt>%{_jnidir}</tt> Основной JNI jar- | * <tt>%{_jnidir}</tt> Основной JNI jar-репозиторий. | ||
* <tt>%{_javadir}</tt> Основной jar- | * <tt>%{_javadir}</tt> Основной jar-репозиторий. | ||
Если мы ничего не находим, поиск повторяется для <tt>foo/bar.jar</tt>, <tt>foo/bar</tt>, <tt>foo.jar</tt>, и наконец <tt>foo</tt> каталог. Заметим, поиск выполняется для пары jar/директория, т.е. поддиректория расположенная в более конкретном репозитории будет всегда иметь превосходство перед jar с таким же именем, но расположенном в менее конкретном репозитории. | |||
==== find-jar ==== | ==== find-jar ==== | ||
find-jar {объект} | |||
Команда | Команда <tt>find-jar</tt> проверяет расположение указанного объекта. Возвращает имя jar-файл или директории. Эта утилита предназначена исключительно для тестирования расположения объекта и не должна использоваться в скриптах. Данная команда является обязательной даже для определения classpath'а для единственного объекта, в связи с тем что поиск для единственного объекта может приводить к различным результатам, когда объект в итоге раскрывается в директорию. | ||
[bob@sys dir]$ find-jar jndi | |||
/usr/lib/jvm-exports/java-1.3.1-blackdown/jndi.jar | |||
==== build-classpath ==== | ==== build-classpath ==== | ||
build-classpath {объект...} | |||
Команда <tt>build-classpath</tt> находит classpath, следуя основным правилам разрешения. Аргументами команды -- является список объектов. Если объект разрешается в директорию, все jar-файлы этой директории будут включены в classpath. | |||
Результат выполнения build-classpath: | |||
[bob@sys dir]$ export JAVA_HOME=/usr/lib/jvm/java-1.3.1-blackdown | |||
[bob@sys dir]$ build-classpath jsse javamail/mailapi jaxp_parser_impl | |||
/usr/share/java-1.3.1/jsse/jcert-1.0.3.01.jar:/usr/share/java-1.3.1/jsse/jnet-1.0.3.01.jar:/usr/share/java-1.3.1/jsse/jsse-1.0.3.01.jar:/usr/share/java/javamail/mailapi.jar:/usr/share/java/jaxp_parser_impl.jar | |||
[bob@sys dir]$ export JAVA_HOME=/usr/lib/jvm/java-1.4.1-sun | |||
[bob@sys dir]$ build-classpath jsse javamail/mailapi jaxp_parser_impl | |||
/usr/lib/jvm-exports/java-1.4.1-sun/jsse.jar:/usr/share/java/javamail/mailapi.jar:/usr/share/java/jaxp_parser_impl.jar</pre> | |||
==== Рекомендованная практика построения classpath, состоящей из достаточной и опциональной частей ==== | |||
Построение classpath с достаточной и опциональной частью: | |||
CLASSPATH=$(build-classpath list_of_required_elements):$(build-classpath list_of_optional_elements 2> /dev/null) | |||
/ | |||
==== build-jar-repository ==== | |||
build-jar-repository [[-s] | [--soft] | [--symbolic] | [-h] | [--hard] | [-c] | [--copy]] [[-p] | [--preserve-naming]] {директория} {объект...} | |||
Команда <tt>build-jar-repository</tt> создает структуру директорий из симлинков на jar-файлы, по следующим правилам. Принимает в качестве аргументов имя директории и список объектов. После чего попытается создать набор символьных ссылок <tt>[foo][bar]xxx.jar</tt> в указанной директории для каждого запрошенного <tt>foo/bar</tt> объекта<ref>Единичный объект может быть разрешен в директорию с большим числом jar-файлов.</ref>. Особая структура имен символьных ссылок делает возможным определить были ли они созданным именно этой командой, и является необходимым условием для использования <tt>rebuild-jar-repository</tt>. Утилите <tt>build-jar-repository</tt> можно указать какого типа должны быть создаваемые объекты: символьной, жесткой ссылкой или копией файла. По умолчанию -- создается символьная ссылка, другой тип должен быть использован только для сильно поврежденного ПО. | |||
===== Инкрементное использование ===== | |||
<tt>build-jar-repository</tt>' может быть свободно использован для одной и той же директории. Предыдущие симлинки не будут удалены. Удаление символьных ссылок в директории, производится только пользователем, утилита этого не делает. | |||
==== Задание имен, для безопасного перемещения ===== | |||
Если вы хотите распространить директория с jar копиями или ссылками на них, вы можете использовать ключ <tt>--preserve-naming</tt>. При его использовании, <tt>build-jar-repository</tt> будет создавать файлы с именами наиболее близкими к оригинальным. Заметим, что это приведет к будущим проблемам при обновления этого репозитория. Не используйте данный ключ, пока вы точно не будете уверены, что вы делаете. | |||
<tt>--preserve-naming</tt> включает в себя <tt>--copy</tt>, пока не определено обратного. | |||
===== Результат выполнения build-jar-repository ===== | |||
[bob@sys dir]$ export JAVA_HOME=/usr/lib/jvm/java-1.3.1-blackdown | [bob@sys dir]$ export JAVA_HOME=/usr/lib/jvm/java-1.3.1-blackdown | ||
[bob@sys dir]$ build-jar-repository lib jsse javamail/mailapi | [bob@sys dir]$ build-jar-repository lib jsse javamail/mailapi | ||
[bob@sys dir]$ build-jar-repository lib jaxp_parser_impl | [bob@sys dir]$ build-jar-repository lib jaxp_parser_impl | ||
[bob@sys dir]$ tree lib | [bob@sys dir]$ tree lib | ||
[nim@rousalka nim]$ tree lib | [nim@rousalka nim]$ tree lib | ||
lib | lib | ||
|-- [javamail][mailapi].jar -> /usr/share/java/javamail/mailapi.jar | |-- [javamail][mailapi].jar -> /usr/share/java/javamail/mailapi.jar | ||
|-- [jaxp_parser_impl].jar -> /usr/share/java/jaxp_parser_impl.jar | |-- [jaxp_parser_impl].jar -> /usr/share/java/jaxp_parser_impl.jar | ||
|-- [jsse]jcert-1.0.3.01.jar -> /usr/share/java-1.3.1/jsse/jcert-1.0.3.01.jar | |-- [jsse]jcert-1.0.3.01.jar -> /usr/share/java-1.3.1/jsse/jcert-1.0.3.01.jar | ||
|-- [jsse]jcert.jar -> /usr/share/java-1.3.1/jsse/jcert.jar | |-- [jsse]jcert.jar -> /usr/share/java-1.3.1/jsse/jcert.jar | ||
|-- [jsse]jnet-1.0.3.01.jar -> /usr/share/java-1.3.1/jsse/jnet-1.0.3.01.jar | |-- [jsse]jnet-1.0.3.01.jar -> /usr/share/java-1.3.1/jsse/jnet-1.0.3.01.jar | ||
|-- [jsse]jnet.jar -> /usr/share/java-1.3.1/jsse/jnet.jar | |-- [jsse]jnet.jar -> /usr/share/java-1.3.1/jsse/jnet.jar | ||
|-- [jsse]jsse-1.0.3.01.jar -> /usr/share/java-1.3.1/jsse/jsse-1.0.3.01.jar | |-- [jsse]jsse-1.0.3.01.jar -> /usr/share/java-1.3.1/jsse/jsse-1.0.3.01.jar | ||
`-- [jsse]jsse.jar -> /usr/share/java-1.3.1/jsse/jsse.jar | `-- [jsse]jsse.jar -> /usr/share/java-1.3.1/jsse/jsse.jar | ||
==== rebuild-jar-repository ==== | ==== rebuild-jar-repository ==== | ||
rebuild-jar-repository [[-s] | [--soft] | [--symbolic] | [-h] | [--hard] | [-c] | [--copy]] {директория} | |||
Команда <tt>rebuild-jar-repository</tt> обновляет jar-репозиторий, созданный <tt>build-jar-repository</tt>. Аргументом команды является имя директории, и предназначена для исправления символьных ссылок после изменения $JAVA_HOME, для совместимости с новым JVM. Опции для типа создаваемых объектов такие же что и у <tt>build-jar-repository</tt>. | |||
==== Смешанное использование ==== | |||
Специфичные имена символьных ссылок, которые создаются <tt>build-jar-repository</tt> и <tt>rebuild-jar-repository</tt> позволяют смешивать автоматические ссылки, созданные в ручную и обычные файлы в директориях, обрабатываемых этими утилитами. Скрипты меняют только имена собственных ссылок | |||
Результаты выполнения rebuild-jar-repository: | |||
[bob@sys dir]$ export export JAVA_HOME=/usr/lib/jvm/java-1.4.1-sun | |||
[bob@sys dir]$ rebuild-jar-repository lib | |||
[bob@sys dir]$ tree lib | |||
lib | |||
|-- [javamail][mailapi].jar -> /usr/share/java/javamail/mailapi.jar | |||
|-- [jaxp_parser_impl].jar -> /usr/share/java/jaxp_parser_impl.jar | |||
`-- [jsse].jar -> /usr/lib/jvm-exports/java-1.4.1-sun/jsse.jar | |||
==== Невозможность разрешения объекта ==== | |||
В отличие от <tt>build-jar-repository</tt>, <tt>rebuild-jar-repository</tt> будет создавать символьные ссылки. Это сделано для предотвращения потери объектов при сломанной java-подсистеме.<ref>Если устранить проблемы: установка нужных jar'ов или выбор более полной версии JVM, то '''rebuild-jar-repository''' отработает нормально, как-будто ничего и не случалось.</ref> Созданная символьная ссылка указывает в "никуда" и всегда должна быть "поломанной". | |||
== Примечания == | == Примечания == | ||
<references/> | <references/> | ||
{{Category navigation|title=Java|category=Java|sortkey={{SUBPAGENAME}}}} |
Текущая версия от 19:33, 2 марта 2010
JPackage JavaTM 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 и приводить к коварным падениям и ошибкам.
Это не удивительно, что сложные Java системы имеют тенденцию костенеть очень быстро. И приводить к быстрому росту стоимости обслуживания, что в свою очередь приводит к падению интереса к поддержанию таких систем в рабочем состоянии. И в конечном итоге люди бросают этим заниматься.
Данная ситуация не совместима с типичной быстро развивающейся Linux-системой. Чтобы достигнуть своей цели, создания дружественных для пользователей и администраторов методов rpm упаковки Java приложений, JPackage Project должен развить свою системную инфраструктуру и строгие правила упаковки.
Глава 1. Общие правила
Будь модульным
По возможности модуль должен быть разбит на образующие компоненты. Компонент должен иметь уникальное имя и расположение. Только одна версия данного компонента должна быть установлена. Приложения, разделяющие одинаковые зависимости, должны зависеть от внешних пакетов, не встроенных версий.
Be vendor and implementation agnostic
Пользователь должен иметь возможность выбора между различными реализациями одного и того же компонента, в особенности когда их лицензионные условия не эквивалентны или когда их уровень законченности отличается. Необходимо учесть возможность параллельной установки таких компонентов, с возможностью самостояетльного выбора пользователем между ними или лучшего из них системой[2]
Be distribution agnostic
Пакеты должны работать на большинстве основных rpm-based дистрибутивах. Это означает следование стандартам, таких как Linux Standard Base, Filesystem Hierarchy Standard или freedesktop.org спецификациям
Прежде всего запрещено использование дистрибутивно-специфичных особенностей[3]
Отметим, что это - прагматическое чтение стандартов. Средства обслуживания не определены, но в основном находятся в состоянии готовности для использования в проекте[4], дистрибутивно-специфичные адаптации допускаются при условии их не вмешательства в общее использование.
Глава 2. Назначение имен
Имя пакета
Пакеты должны быть названы общим именем их оригинального проекта в нижнем регистре. Когда пакет предоставляет расширение, которое было в какой-то момент заложено в Java стандарте, -ext (как external) суффикс должен быть добавлен, для различия между именем пакета и именем расширения. И JVM, которое включает данное расширение, и автономный пакет расширения, должны иметь оригинальное название как virtual Provides.
JVM должны носить имя -- java-standard_version-vendor. Оригинальное название с сайта не должно использоваться в связи с широкой практикой разброса в именовании от вендора к вендроу и от версии к версии.
Название Jar-файлов
- Если пакет предоставляет только один jar, он должен иметь тоже название что и пакет, с добавлением версии продукта.
jaf-1.0.2.jar
- Безверсионная символьная ссылка, смотрящая на оригинальный файл тоже должна быть предоставлена (провайдена)
jaf-1.0.2.jar jaf.jar -> jaf-1.0.2.jar
- Если название проекта и часто используемое jar-имя отличаются, символьная ссылка на принятое имя должна так же быть предоставлена (провайдиться).
jaf-1.0.2.jar jaf.jar -> jaf-1.0.2.jar activation.jar -> jaf-1.0.2.jar
- Если пакет состоит из нескольких jar'ов, их обычные названия также будут использоваться.
ant-1.5.3.jar ant.jar -> ant-1.5.3.jar ant-optional-1.5.3.jar ant-optional.jar -> ant-optional-1.5.3.jar
- Если число jar'ов превышает два, или если они были предоставлены в виде монолитного jar'а, файлы должны быть помещены в поддиректорию с названием пакета (так же как и для одиночного jar'а).
javamail javamail/imap-1.3.jar javamail/imap.jar -> imap-1.3.jar javamail/mailapi-1.3.jar javamail/mailapi.jar -> mailapi-1.3.jar javamail/pop3-1.3.jar javamail/pop3.jar -> pop3-1.3.jar javamail/smtp-1.3.jar javamail/smtp.jar -> smtp-1.3.jar
- Если проект предлагает выбор метода упаковки, между одним монолитным jar'ом или разбиением на несколько более мелких, упаковка с разбиением будет предпочтительнее.
Глава 3. Структура директорий
Основная структура директорий, предоставляемая пакетом jpackage-utils состоит из:
%{_javadir}
RPM макрос %{_javadir} задает главный jar-репозиторий. Исторически это была единственная директория, используемая 1.0 JPakage, прежде чем упаковочные ограничения привели к более сложной системе. Он обычно раскрывается в /usr/share/java.
Все jar-файлы и директории с jar-файлами, которые не зависят от конретной версии Java-стандарта или JNI должны быть установлены в %{_javadir}.
От %{_javadir} мы получаем %{_javadir}-ext. Все jar-файлы и директории jar-файлов, которые зависят от конкретной версии Java-стандарта, но не от JNI, должны быть установлены в %{_javadir}-ext.
Директории %{_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-стандарт как известно меняется довольно сильно между младшими версиями, поэтому мы должны учитывать полную версию и различия между %{_javadir}-1.4.0 и %{_javadir}-1.4.1.
Версионные особенности Java-стандарт при использовании в репозитории
/usr/share/java-ext/jsse /usr/share/java-ext/jsse/jcert-1.0.3.01.jar /usr/share/java-ext/jsse/jcert.jar -> jcert-1.0.3.01.jar /usr/share/java-ext/jsse/jnet-1.0.3.01.jar /usr/share/java-ext/jsse/jnet.jar -> jnet-1.0.3.01.jar /usr/share/java-ext/jsse/jsse-1.0.3.01.jar /usr/share/java-ext/jsse/jsse.jar -> jsse-1.0.3.01.jar /usr/share/java-1.3.0/jsse -> /usr/share/java-ext/jsse
/usr/share/java-1.3.1/jsse -> /usr/share/java-ext/jsse
Используется для множества 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'ами ограничены в функциональности и производители поставляют неограниченные по функциональности файлы политик отдельно. Зачастую эти файлы -- часть какой-то версии Java-стандарта конкретного вендора (типа java-1.4.2-sun).
JCE файлы политик для Sun's J2SE 1.4.2:
/usr/lib/jvm-private/java-1.4.2-sun /usr/lib/jvm-private/java-1.4.2-sun/jce /usr/lib/jvm-private/java-1.4.2-sun/jce/vanilla /usr/lib/jvm-private/java-1.4.2-sun/jce/vanilla/US_export_policy.jar /usr/lib/jvm-private/java-1.4.2-sun/jce/vanilla/local_policy.jar /usr/lib/jvm-private/java-1.4.2-sun/jce/unlimited /usr/lib/jvm-private/java-1.4.2-sun/jce/unlimited/US_export_policy.jar /usr/lib/jvm-private/java-1.4.2-sun/jce/unlimited/local_policy.jar
Различные версии jar'ов JCE-политик в дальнейшем управляются через систему альтернатив, использующую ссылку, которая указывает на соответствующий jar-файл в JVM jre/lib/security директории, с большим приоритетом на более функциональную версию чем та что принадлежит JVM.
%{_sysconfdir}/java: /etc/java
%{_sysconfdir}/java содержит основные файлы конфигурации, принадлежащие java-подсистеме, главным образом java.conf.
%{_javadocdir}
Это корень всех установленных javadoc документов. Его расположение и предполагаемое использование обсуждается в данный момент.
Директории зависимые от приложения
- Собственные директории приложения должны располагаться в системе в соответствии с правилами Filesystem Hierarchy Standard
- Если приложению необходимо свое файловое дерево, как в других операционных системах (а FHS требует, чтобы поддиректории были установленные в разные части системы), макрос %{_datadir}/appname должен быть использован как корневая-домашняя директория с символьными ссылками, указывающими на реальное расположение поддиректорий в системе. Конечно лучше изменить приложение, чтобы оно понимало правильное разделение файлов и отменяло пляску с символьными ссылками.
FHS и централизованная домашняя директория приложения:
/usr/share/tomcat4 /usr/share/tomcat4/bin /usr/share/tomcat4/common -> /var/lib/tomcat4/common /usr/share/tomcat4/conf -> /etc/tomcat4 /usr/share/tomcat4/logs -> /var/log/tomcat4 /usr/share/tomcat4/server -> /var/lib/tomcat4/server /usr/share/tomcat4/shared -> /var/lib/tomcat4/shared /usr/share/tomcat4/temp -> /var/cache/tomcat4/temp /usr/share/tomcat4/webapps ->/var/lib/tomcat4/webapps /usr/share/tomcat4/work -> /var/cache/tomcat4/work
- Велосипеды лучше не создавать. Если директория всегда имеет только один единственный подкаталог, избавьтесь от него[5]
- Если приложение использует classpath-компоненты, которые не являются jar-файлами, они должны быть установлены в собственную директорию приложения
zip, war и другие файлы архивов классов
Любой может столкнуться с другими типами архивов используемых в classpaths. Если прямой необходимости в использовании таких файлов нет, то следует конвертировать их в jar. Это особенно важно для zip-файлов, которые были одно время в широком использовании, но в последствии вышли из употребления.
- Если приложение состоит из собственных jar-файлов, то это всегда будет только одного пользователя, и они могут быть установлены в собственные директории приложения.
Собственные jar-файлы
Это предполагает, что стандартные правила, не могут быть использованы для построения classpath-приложения, таким образом эта часть должна быть обработана самим приложением или мантейнером пакета[6]. Тем не менее, когда приложение может и будут читать собственный jar-репозиторий, мы действительно обеспечиваем средствами для управления частями репозитория, которые используются совместно с другими приложениями.
Глава 4. Скрипты и выбор classpath при запуске
Мы предполагаем что верные значения переменных окружения уже выставлены, по крайней мене $JAVA_HOME для выбора JVM в %{_jvmdir}, и в конечном счете $JAVACMD, $LD_ASSUME_KERNEL, $LANG, и $JAVA_COMPILER переменные.
FIXME: Исправить
Текущая реализация данной политики не столь хороша как хотелось бы и тащит с собой кучу наследственного мусора. Нормальная реализация будет использовать значения переменных из /.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 является JVM стандартным Java уровнем согласия как видно из
[bob@sys dir]$ $JAVACMD -version
- %{_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'а для единственного объекта, в связи с тем что поиск для единственного объекта может приводить к различным результатам, когда объект в итоге раскрывается в директорию.
[bob@sys dir]$ find-jar jndi /usr/lib/jvm-exports/java-1.3.1-blackdown/jndi.jar
build-classpath
build-classpath {объект...}
Команда build-classpath находит classpath, следуя основным правилам разрешения. Аргументами команды -- является список объектов. Если объект разрешается в директорию, все jar-файлы этой директории будут включены в classpath.
Результат выполнения build-classpath:
[bob@sys dir]$ export JAVA_HOME=/usr/lib/jvm/java-1.3.1-blackdown [bob@sys dir]$ build-classpath jsse javamail/mailapi jaxp_parser_impl /usr/share/java-1.3.1/jsse/jcert-1.0.3.01.jar:/usr/share/java-1.3.1/jsse/jnet-1.0.3.01.jar:/usr/share/java-1.3.1/jsse/jsse-1.0.3.01.jar:/usr/share/java/javamail/mailapi.jar:/usr/share/java/jaxp_parser_impl.jar [bob@sys dir]$ export JAVA_HOME=/usr/lib/jvm/java-1.4.1-sun [bob@sys dir]$ build-classpath jsse javamail/mailapi jaxp_parser_impl
/usr/lib/jvm-exports/java-1.4.1-sun/jsse.jar:/usr/share/java/javamail/mailapi.jar:/usr/share/java/jaxp_parser_impl.jar
Рекомендованная практика построения classpath, состоящей из достаточной и опциональной частей
Построение classpath с достаточной и опциональной частью:
CLASSPATH=$(build-classpath list_of_required_elements):$(build-classpath list_of_optional_elements 2> /dev/null)
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 объекта[7]. Особая структура имен символьных ссылок делает возможным определить были ли они созданным именно этой командой, и является необходимым условием для использования rebuild-jar-repository. Утилите build-jar-repository можно указать какого типа должны быть создаваемые объекты: символьной, жесткой ссылкой или копией файла. По умолчанию -- создается символьная ссылка, другой тип должен быть использован только для сильно поврежденного ПО.
Инкрементное использование
build-jar-repository' может быть свободно использован для одной и той же директории. Предыдущие симлинки не будут удалены. Удаление символьных ссылок в директории, производится только пользователем, утилита этого не делает.
Задание имен, для безопасного перемещения =
Если вы хотите распространить директория с jar копиями или ссылками на них, вы можете использовать ключ --preserve-naming. При его использовании, build-jar-repository будет создавать файлы с именами наиболее близкими к оригинальным. Заметим, что это приведет к будущим проблемам при обновления этого репозитория. Не используйте данный ключ, пока вы точно не будете уверены, что вы делаете.
--preserve-naming включает в себя --copy, пока не определено обратного.
Результат выполнения build-jar-repository
[bob@sys dir]$ export JAVA_HOME=/usr/lib/jvm/java-1.3.1-blackdown [bob@sys dir]$ build-jar-repository lib jsse javamail/mailapi [bob@sys dir]$ build-jar-repository lib jaxp_parser_impl [bob@sys dir]$ tree lib [nim@rousalka nim]$ tree lib lib |-- [javamail][mailapi].jar -> /usr/share/java/javamail/mailapi.jar |-- [jaxp_parser_impl].jar -> /usr/share/java/jaxp_parser_impl.jar |-- [jsse]jcert-1.0.3.01.jar -> /usr/share/java-1.3.1/jsse/jcert-1.0.3.01.jar |-- [jsse]jcert.jar -> /usr/share/java-1.3.1/jsse/jcert.jar |-- [jsse]jnet-1.0.3.01.jar -> /usr/share/java-1.3.1/jsse/jnet-1.0.3.01.jar |-- [jsse]jnet.jar -> /usr/share/java-1.3.1/jsse/jnet.jar |-- [jsse]jsse-1.0.3.01.jar -> /usr/share/java-1.3.1/jsse/jsse-1.0.3.01.jar `-- [jsse]jsse.jar -> /usr/share/java-1.3.1/jsse/jsse.jar
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 позволяют смешивать автоматические ссылки, созданные в ручную и обычные файлы в директориях, обрабатываемых этими утилитами. Скрипты меняют только имена собственных ссылок
Результаты выполнения rebuild-jar-repository:
[bob@sys dir]$ export export JAVA_HOME=/usr/lib/jvm/java-1.4.1-sun [bob@sys dir]$ rebuild-jar-repository lib [bob@sys dir]$ tree lib lib |-- [javamail][mailapi].jar -> /usr/share/java/javamail/mailapi.jar |-- [jaxp_parser_impl].jar -> /usr/share/java/jaxp_parser_impl.jar `-- [jsse].jar -> /usr/lib/jvm-exports/java-1.4.1-sun/jsse.jar
Невозможность разрешения объекта
В отличие от build-jar-repository, rebuild-jar-repository будет создавать символьные ссылки. Это сделано для предотвращения потери объектов при сломанной java-подсистеме.[8] Созданная символьная ссылка указывает в "никуда" и всегда должна быть "поломанной".
Примечания
- ↑ Различные требования, различные ошибки
- ↑ Основанные на лицензионных условиях, известные завершенности, относительное отсутствие ошибок, рекламные проникновения и так далее
- ↑ Как Mandrake'овская gprintf функция.
- ↑ Для примера RPM 4 возможности, или Debian'ская система alternatives(8)...
- ↑ те не создавайте единственный подкаталог для библиотеки в %{_datadir}/appname, только потому что более сложные приложения делают это. Если он всегда будет один, используйте сразу %{_datadir}/appname
- ↑ Hardcoding classpath bits for example
- ↑ Единичный объект может быть разрешен в директорию с большим числом jar-файлов.
- ↑ Если устранить проблемы: установка нужных jar'ов или выбор более полной версии JVM, то rebuild-jar-repository отработает нормально, как-будто ничего и не случалось.