Файл JAR является форматом файла, основанным на популярном формате файла ZIP, и используется для того, чтобы агрегировать много файлов в одного. Файл JAR является по существу файлом zip, который содержит дополнительный каталог META-INF. Файл JAR может быть создан инструментом фляги командной строки, или при использовании API java.util.jar в платформе Java. Нет никакого ограничения на имя файла JAR, это может быть любое юридическое имя файла на определенной платформе.
Во многих случаях файлы JAR не являются только простыми архивами файлов классов java и/или ресурсов. Они используются в качестве стандартных блоков для приложений и расширений. Каталог META-INF, если это существует, используется, чтобы сохранить пакет и данные конфигурации расширения, включая безопасность, управление версиями, расширение и службы.
Каталог META-INF
Следующие файлы/каталоги в каталоге META-INF распознаются и интерпретируются Java 2 Платформы, чтобы сконфигурировать приложения, расширения, загрузчики класса и службы:
MANIFEST.MF
Файл манифеста, который используется, чтобы определить расширение и пакет связанные данные.
INDEX.LIST
Этот файл сгенерирован новой "опцией -i" инструмента фляги, который содержит информацию о расположении для пакетов, определенных в приложении или расширении. Это - часть реализации JarIndex и используемый загрузчиками класса, чтобы ускорить их процесс загрузки класса.
x.SF
Файл подписи для файла JAR. 'x' обозначает основное имя файла.
x.DSA
Файл сигнатурного блока связался с файлом подписи с тем же самым основным именем файла. Это хранилища файлов цифровая подпись соответствующего файла подписи.
services/
Этот каталог хранит все конфигурационные файлы поставщика услуг.
Пары значение-имя и Разделы
Прежде, чем мы пойдем в детали содержания отдельных конфигурационных файлов, некоторое соглашение формата должно быть определено. В большинстве случаев информация, содержавшая в пределах файла манифеста и файлов подписи, представляется как так называемое "имя: оцените" пар, вдохновленных стандартом RFC822. Мы также вызываем эти заголовки пар или атрибуты.
Группы пар значение-имя известны как "раздел". Разделы разделяются от других разделов пустыми строками.
Двоичные данные любой формы представляются как base64. Продолжения требуются для двоичных данных, который заставляет длину строки превышать 72 байта. Примерами двоичных данных являются обзоры и подписи.
Реализации должны поддерживать значения заголовка до 65535 байтов.
Все спецификации в этом документе используют ту же самую грамматику, в которой терминальные символы показывают в фиксированном шрифте ширины, и нетерминальные символы показывают в поверхности курсива.
Спецификация:
раздел: *header +newline непустой раздел: +header +newline новая строка: CR LF | LF | CR (не сопровождаемыйLF) заголовок: назовитезначение: имя: alphanum *headerchar значение: РАСПОЛОЖИТЕ *otherchar новую строку с интервалами *continuation продолжение: РАСПОЛОЖИТЕ *otherchar новую строку с интервалами alphanum: {A-Z} | {a-z} | {0-9} headerchar: alphanum | - | _ otherchar: любой символ UTF-8 кромеNUL, CRиLF
; Также: предотвратить искажение файлов, отправленных через прямую электронную почту, нет ; заголовок запустится с четырех букв "От".
На нетерминальные символы, определенные в вышеупомянутой спецификации, сошлются в следующих спецификациях.
Декларация JAR
Краткий обзор
Декларация файла JAR состоит из основного раздела, сопровождаемого списком разделов для отдельных записей файла JAR, каждый разделенный новой строкой. И основной раздел и отдельные разделы следуют за синтаксисом раздела, определенным выше. У каждого из них есть их собственные определенные ограничения и правила.
Основной раздел содержит безопасность и конфигурационную информацию о файле JAR непосредственно, так же как приложение или расширение, из которого этот файл JAR является частью. Это также определяет основные атрибуты, которые применяются к каждой отдельной явной записи. Ни у какого атрибута в этом разделе не может быть своего имени, равного "Name". Этот раздел завершается пустой строкой.
Отдельные разделы определяют различные атрибуты для пакетов или файлов, содержавшихся в этом файле JAR. Не все файлы в файле JAR должны быть перечислены в декларации как записи, но все файлы, которые должны быть подписаны, должны быть перечислены. Сам файл манифеста не должен быть перечислен. Каждый раздел должен запуститься с атрибута с именем как "Name", и значение должно быть относительным путем к файлу, или абсолютным URL, ссылающимся на данные вне архива.
Если есть многократные отдельные разделы для той же самой записи файла, атрибуты в этих разделах объединяются. Если у определенного атрибута есть различные значения в различных разделах, последний распознается.
Игнорируются атрибуты, которые не понимаются. Такие атрибуты могут включать реализацию определенная информация, используемая приложениями.
Явная Спецификация:
файл манифеста: новая строка основного раздела *individual-section основной раздел: новая строка информации о версии *main-attribute информация о версии: номер версииManifest-Version : номер версии: цифра + {цифра.+}* основной атрибут: (любой законный основной атрибут) новая строка отдельный раздел: новая строказначенияName :*perentry-attribute perentry-атрибут: (любой законный атрибут perentry) новая строка новая строка: CR LF | LF | CR (не сопровождаемыйLF) цифра:{0-9}
В вышеупомянутой спецификации атрибуты, которые могут появиться в основном разделе, упоминаются как основные атрибуты, тогда как атрибуты, которые могут появиться в отдельных разделах, упоминаются как атрибуты на запись. Определенные атрибуты могут появиться и в основном разделе и в отдельных разделах, когда значение атрибута на запись переопределяет основное значение атрибута для указанной записи. Два типа атрибутов определяются следующим образом.
Основные Атрибуты
Основные атрибуты являются атрибутами, которые присутствуют в основном разделе декларации. Они попадают в следующие различные группы:
общие основные атрибуты
Явная версия: Определяет версию файла манифеста. Значение является законным номером версии, как описано в вышеупомянутой спецификации.
Создаваемый-: Определяет версию и поставщика реализации java, сверху которой сгенерирован этот файл манифеста. Этот атрибут сгенерирован инструментом jar.
Версия подписи: Определяет версию подписи файла фляги. Значение должно быть допустимой строкой номера версии.
Путь к классу: значение этого атрибута определяет относительные URL расширений или библиотек, в которых нуждаются это приложение или расширение. URL разделяются одними или более пробелами. Загрузчик класса приложения или расширения использует значение этого атрибута, чтобы создать его внутренний путь поиска.
атрибут определил для автономных приложений: Этот атрибут используется автономными приложениями, которые связываются в исполнимые файлы фляги, которые могут быть вызваны средой выполнения Java непосредственно, выполняя "java -jar x.jar".
Основной класс: значение этого атрибута определяет относительный путь основного класса приложений, который средство запуска загрузит во время запуска. Значению нельзя было добавить расширение .class к имени класса.
атрибуты определили для апплетов: Эти атрибуты используются апплетом, который связывается в файлы JAR, чтобы определить требования, версию и информацию о расположении для расширений, от которых зависит этот апплет. (см. Управление версиями Расширения).
Список расширения: Этот атрибут указывает на расширения, которые необходимы апплету. У каждого расширения, перечисленного в этом атрибуте, будет ряд дополнительных атрибутов, что использование апплета, чтобы определить, какой версии и поставщика расширения это требует.
<расширение> - Имя расширения: Этот атрибут является уникальным именем расширения. Плагин Java сравнит значение этого атрибута с атрибутом Имени расширения в декларациях установленных расширений, чтобы определить, устанавливается ли расширение.
<расширение> - Версия спецификации: Этот атрибут определяет минимальную версию спецификации расширения, которая требуется апплетом. Плагин Java сравнит значение этого атрибута с атрибутом Версии спецификации установленного расширения, чтобы определить, современно ли расширение.
<расширение> - Версия реализации: Этот attritute определяет минимальный номер версии реализации расширения, который требуется апплетом. Плагин Java сравнит значение этого атрибута с атрибутом Версии реализации установленного расширения, чтобы видеть, должна ли более свежая реализация быть загружена.
<расширение> - Идентификатор поставщика реализации: Этот атрибут может использоваться, чтобы идентифицировать поставщика реализации расширения, если апплет требует реализации от определенного поставщика. Плагин Java сравнит значение этого атрибута с атрибутом Идентификатора поставщика реализации установленного расширения.
<расширение> - URL реализации: Этот атрибут определяет URL, который может использоваться, чтобы получить новую версию расширения, если необходимая версия уже не устанавливается.
атрибут определил для идентификации расширения: Этот атрибут используется расширениями, чтобы определить их уникальные идентификационные данные.
Имя расширения: Этот атрибут определяет имя для расширения, содержавшегося в файле Фляги. Имя должно быть уникальным идентификатором, таким как имя основного пакета, включающего расширение.
атрибуты, определенные для расширения и информации об управлении версиями и изоляции пакета: Эти атрибуты определяют функции расширения, из которого файл JAR является частью. Значение этих атрибутов применяется ко всем пакетам в файле JAR, но может быть переопределено атрибутами на запись.
Заголовок реализации: значение является строкой, которая определяет заголовок реализации расширения.
Версия реализации: значение является строкой, которая определяет версию реализации расширения.
Поставщик реализации: значение является строкой, которая определяет организацию, которая поддерживает реализацию расширения.
Идентификатор поставщика реализации: значение является строковым идентификатором, который уникально определяет организацию, которая поддерживает реализацию расширения.
URL реализации: Этот атрибут определяет URL, от которого реализация расширения может быть загружена с.
Заголовок спецификации: значение является строкой, которая определяет заголовок спецификации расширения.
Версия спецификации: значение является строкой, которая определяет версию спецификации расширения.
Поставщик спецификации: значение является строкой, которая определяет организацию, которая поддерживает спецификацию расширения.
Изолированный: Этот атрибут определяет, изолируется ли этот файл JAR или нет. Значение может быть или "истиной" или "ложью", регистр игнорируется. Если это устанавливается в "истину", то все пакеты в файле JAR принимаются значение по умолчанию, чтобы быть изолированными, если они не определяются иначе индивидуально.
Атрибуты на запись
Атрибуты на запись применяются только к отдельной записи файла JAR, с которой явная запись связывается с. Если тот же самый атрибут также появился в основном разделе, то значение атрибута на запись перезаписывает значение основного атрибута. Например, если у файла JAR a.jar есть следующий явный контент:
Это означает, что все пакеты, заархивированные в a.jar, изолируются, за исключением того, что пакет foo.bar не.
Атрибуты на запись попадают в следующие группы:
атрибуты определили для содержания файла:
Тип контента: Этот атрибут может использоваться, чтобы определить тип MIME и подтип данных для определенной записи файла в файле JAR. Значение должно быть строкой в форме типа/подтипа. Например "image/bmp" является типом изображения с подтипом bmp (представляющий битовый массив). Это указало бы на запись файла как на изображение с данными, хранившими как битовый массив. RFC 1521 и 1522обсуждает и определяет определение типов MIME.
атрибуты, определенные для информации об управлении версиями и изоляции пакета: Они - тот же самый набор атрибутов, определенных выше как основные атрибуты, который определяет информацию об управлении версиями и изоляции пакета расширения. Когда использующийся атрибуты согласно записи, эти атрибуты перезаписывают основные атрибуты, но только применитесь к отдельному файлу, определенному явной записью.
атрибут определил для бобовых объектов:
Боб Java: Определяет, является ли определенная запись файла фляги Бобовым объектом Java или нет. Значение должно быть или "истиной" или "ложью", регистр игнорируется.
атрибуты определили для того, чтобы подписаться: Эти атрибуты используются для подписания и проверки целей. Больше деталей здесь.
x-Digest-y: имя этого атрибута определяет имя алгоритма обзора, используемого, чтобы вычислить значение обзора для соответствующей записи файла фляги. Значение этого атрибута хранит фактическое значение обзора. Префикс 'x' определяет имя алгоритма, и дополнительный суффикс 'y' указывает, к которому языку значение обзора должно быть проверено против.
Волшебство: Это - дополнительный атрибут, который может использоваться приложениями, чтобы указать, как верификатор должен вычислить значение обзора, содержавшееся в явной записи. Значение этого атрибута является рядом запятой разделенные зависящие от контекста строки. Подробное описание здесь.
Файл JAR со знаком
Краткий обзор
Файл JAR может быть подписан при использовании командной строки jarsigner инструмент или непосредственно через java.security API. Каждая запись файла, включая неподпись связанные файлы в META-INF каталог, будет подписан, если файл JAR будет подписан jarsigner инструментом. Подпись связанные файлы:
META-INF/MANIFEST.MF
META-INF/*.SF
META-INF/*.DSA
META-INF/*.RSA
META-INF/SIG-*
Отметьте это, если такие файлы располагаются в META-INF подкаталоги, их не считают связанными с подписью. Нечувствительные к регистру версии этих имен файлов резервируются и не будут также подписаны.
Подмножества файла JAR могут быть подписаны при использовании java.security API. Файл JAR со знаком является точно тем же самым как исходным файлом JAR, за исключением того, что его декларация обновляется, и два дополнительных файла добавляются к META-INF каталог: файл подписи и файл сигнатурного блока. Когда jarsigner не используется, программа подписания должна создать и файл подписи и файл сигнатурного блока.
Для каждого файла запись входила в систему файл JAR со знаком, отдельная явная запись создается для этого, пока это уже не существует в декларации. Каждая явная запись перечисляет один или более атрибутов обзора и дополнительный Волшебный атрибут.
Файл подписи
Каждое подписывающее лицо представляется файлом подписи с расширением .SF. Главная часть файла подобна файлу манифеста. Это состоит из основного раздела, который включает информацию, предоставленную подписывающим лицом, но не определенный для любой определенной записи файла фляги. В дополнение к Signature-Version и Created-By атрибуты (см. Основные Атрибуты), основной раздел могут также включать следующие атрибуты безопасности:
x-Digest-Manifest-Main-Attributes (где x является стандартным именем a java.security.MessageDigest алгоритм): значение этого атрибута является значением обзора основных атрибутов декларации.
x-Digest-Manifest (где x является стандартным именем a java.security.MessageDigest алгоритм): значение этого атрибута является значением обзора всей декларации.
Основной раздел сопровождается списком отдельных записей, имена которых должны также присутствовать в файле манифеста. Каждая отдельная запись должна содержать, по крайней мере, обзор своей соответствующей записи в файле манифеста.
Пути или URL, появляющиеся в файле манифеста, но не в файле подписи, не используются в вычислении.
Проверка допустимости подписи
Успешная проверка файла JAR происходит, если подпись (и) допустима, и ни один из файлов, которые были в файле JAR, когда подписи были сгенерированы, были изменены с тех пор. Проверка файла JAR включает следующие шаги:
Проверьте подпись по файлу подписи, когда декларация сначала анализируется. Для эффективности можно помнить эту проверку. Отметьте, что эта проверка только проверяет направлений подписи непосредственно, не фактических архивных файлов.
Если x-Digest-Manifest атрибут существует в файле подписи, проверьте значение против обзора, вычисленного по всей декларации. Если больше чем один x-Digest-Manifest атрибут существует в файле подписи, проверьте, что по крайней мере один из них соответствует расчетное значение обзора.
Если x-Digest-Manifest атрибут не существует в файле подписи или ни одном из значений обзора, вычисленных в предыдущем соответствии шага, затем менее оптимизированная проверка выполняется:
Если x-Digest-Manifest-Main-Attributes запись существует в файле подписи, проверьте значение против обзора, вычисленного по основным атрибутам в файле манифеста. Если это вычисление перестало работать, то проверка файла JAR перестала работать. Это решение можно помнить для эффективности. Если x-Digest-Manifest-Main-Attributes запись не существует в файле подписи, его небытие не влияет на проверку файла JAR, и явные основные атрибуты не проверяются.
Проверьте значение обзора в каждом разделе информации об исходном файле в файле подписи против значения обзора, вычисленного против соответствующей записи в файле манифеста. Если какое-либо из значений обзора не соответствует, то проверка файла JAR перестала работать.
Одна причина значение обзора файла манифеста, который сохранен в x-Digest-Manifest атрибут, возможно, не равняется значению обзора текущего файла манифеста, то, что один или более файлов были добавлены к файлу JAR (использующий инструмент фляги) после того, как подпись (и таким образом файл подписи) была сгенерирована. Когда инструмент фляги используется, чтобы добавить файлы, файл манифеста изменяется (разделы добавляются к этому для новых файлов), но файл подписи не. Проверку все еще считают успешной, если ни один из файлов, которые были в файле JAR, когда подпись была сгенерирована, не был изменен с тех пор, который имеет место, равняются ли значения обзора в разделах незаголовка файла подписи значениям обзора соответствующих разделов в файле манифеста.
Для каждой записи в декларации проверьте значение обзора в файле манифеста против обзора, вычисленного по фактическим данным, на которые ссылаются на "Имя:" атрибут, который определяет или путь файла прямого доступа или URL. Если какое-либо из значений обзора не соответствует, то проверка файла JAR перестала работать.
Файл манифеста в качестве примера:
Manifest-Version: 1.0
Created-By: 1.7.0 (Sun Microsystems Inc.)
Name: common/class1.class
SHA-256-Digest: (base64 representation of SHA-256 digest)
Name: common/class2.class
SHA1-Digest: (base64 representation of SHA1 digest)
SHA-256-Digest: (base64 representation of SHA-256 digest)
Соответствующий файл подписи был бы:
Signature-Version: 1.0
SHA-256-Digest-Manifest: (base64 representation of SHA-256 digest)
SHA-256-Digest-Manifest-Main-Attributes: (base64 representation of SHA-256 digest)
Name: common/class1.class
SHA-256-Digest: (base64 representation of SHA-256 digest)
Name: common/class2.class
SHA-256-Digest: (base64 representation of SHA-256 digest)
Волшебный Атрибут
Другое требование, чтобы проверить подписи на данной явной записи - то, что верификатор понимает значение или значения Волшебного значения пары ключей в явной записи той записи.
Волшебный атрибут является дополнительным, но требуется, что синтаксический анализатор понимает значение ключа Magic записи, если это проверяет что подпись записи.
Значение или значения Волшебного атрибута являются рядом разделенных от запятой зависящих от контекста строк. Пробелы прежде и после запятых игнорируются. Регистр игнорируется. Точное значение волшебных атрибутов специализировано. Эти значения указывают, как вычислить значение хэш-функции, содержавшееся в явной записи, и поэтому крайне важны для надлежащей проверки подписи. Ключевые слова могут использоваться для динамического или встроенного контента, многократных хешей для многоязычных документов, и т.д.
Вот два примера потенциального использования Волшебного атрибута в файле манифеста:
Name: http://www.example-scripts.com/index#script1
SHA-256-Digest: (base64 representation of SHA-256 hash)
Magic: JavaScript, Dynamic
Name: http://www.example-tourist.com/guide.html
SHA-256-Digest: (base64 representation of SHA-256 hash)
SHA-256-Digest-French: (base64 representation of SHA-256 hash)
SHA-256-Digest-German: (base64 representation of SHA-256 hash)
Magic: Multilingual
В первом примере эти Волшебные значения могут указать, что результатом запроса http является сценарий, встроенный в документ, в противоположность документу непосредственно, и также что сценарий сгенерирован динамически. Эти два сведения указывают, как вычислить значение хэш-функции, с которым можно сравнить значение обзора декларации, таким образом сравнивая действительную подпись.
Во втором примере Волшебное значение указывает, что полученный документ, возможно, был согласован контентом относительно определенного языка, и что обзор, чтобы проверить против зависит, на котором языке полученный документ пишется в.
Цифровые подписи
Цифровая подпись является версией со знаком .SF файл подписи. Они - двоичные файлы, не предназначенные, чтобы быть интерпретированными людьми.
У файлов цифровой подписи есть те же самые имена файлов как.SF файлы, но различные расширения. Расширение изменяется в зависимости от типа цифровой подписи.
.RSA (Подпись PKCS7, SHA 256 + RSA)
.DSA (Подпись PKCS7, DSA)
Файлы цифровой подписи для алгоритмов подписи, не упомянутых выше, должны находиться в META-INF у каталога и есть префикс"SIG-". corresonding файл подписи (.SF файл), должен также иметь тот же самый префикс.
Для тех форматов, которые не поддерживают внешние данные со знаком, файл должен состоять из копии со знаком .SF файл. Таким образом некоторые данные могут быть дублированы, и верификатор должен сравнить эти два файла.
Форматы, которые поддерживают внешние данные любая ссылка .SF файл, или выполняют вычисления на этом с неявной ссылкой.
Каждый .SF у файла могут быть многократные цифровые подписи, но те подписи должны быть сгенерированы тем же самым юридическим лицом.
Расширения файла могут быть 1 - 3 alphanum символами. Игнорируются нераспознанные расширения.
Примечания по Файлам Декларации и Подписи
Следующее является списком дополнительных ограничений и правил, которые применяются к файлам подписи и декларации.
Перед парсингом:
Если последний знак файла является символом EOF (кодируйте 26), EOF обрабатывается как пробел. Две новых строки добавляются (один для редакторов, которые не помещают новую строку в конце последней строки, и тот так, чтобы у грамматики не было к особому случаю последней записи, у которой, возможно, нет пустой строки после этого).
Атрибуты:
Во всех случаях для всех разделов игнорируются атрибуты, которые не понимаются.
Названия атрибута являются нечувствительными к регистру. Программы, которые генерируют декларацию и файлы подписи, должны использовать случаи, показанные в этой спецификации как бы то ни было.
Названия атрибута не могут быть повторены в пределах раздела.
Версии:
Явная версия и Версия подписи должны быть первыми, и в точно, что случай (так, чтобы они могли быть распознаны легко как волшебство, представляет в виде строки). Кроме этого, порядок атрибутов в пределах основного раздела не является существенным.
Упорядочивание:
Порядок отдельных явных записей не является существенным.
Порядок отдельных записей подписи не является существенным, за исключением того, что обзоры, которые подписываются, находятся в том порядке.
Длина строки:
Никакая строка не может быть более длинной чем 72 байта (не символы) в ее UTF8-закодированной форме. Если значение сделало бы начальную строку дольше чем это, это должно продолжаться на дополнительных строках (каждый запуск с одиночного пробела).
Ошибки:
Если файл не может быть проанализирован согласно этой спецификации, предупреждение должно быть выведено, и ни одной из подписей нельзя доверять.
Ограничения:
Поскольку имена заголовка не могут продолжаться, максимальная длина имени заголовка составляет 70 байтов (должно быть двоеточие и ПРОСТРАНСТВО после имени).
NUL, CR, и LF не могут быть встроены в значения заголовка, и NUL, CR, LF и ":" не может быть встроен в имена заголовка.
Реализации должны поддерживать 65535 байтов (не символ) значения заголовка, и 65535 заголовков на файл. Они могли бы исчерпать память, но там не должны быть трудно кодированы пределы ниже этих значений.
Подписывающие лица:
Технически возможно, что различные объекты могут использовать различные алгоритмы подписания, чтобы совместно использовать единственный файл подписи. Это нарушает стандарт, и дополнительная подпись может быть проигнорирована.
Алгоритмы:
Никакой алгоритм обзора или алгоритм подписи не получают мандат по этому стандарту. Однако, по крайней мере один из MD5 и алгоритма обзора SHA1 должен поддерживаться.
Индекс JAR
Краткий обзор
С тех пор 1.3, JarIndex представляется, чтобы оптимизировать процесс поиска класса загрузчиков класса для сетевых приложений, особенно апплеты. Первоначально, загрузчик класса апплета использует простой линейный алгоритм поиска, чтобы искать каждый элемент на его внутреннем пути поиска, который создается из тега "АРХИВА" или "Пути к классу" основной атрибут. Загрузчик класса загружает и открывает каждый элемент в своем пути поиска, пока класс или ресурс не находится. Если загрузчик класса пытается найти несуществующий ресурс, то все файлы фляги в пределах приложения или апплета должны будут быть загружены. Для больших сетевых приложений и апплетов это могло привести к медленному запуску, вялому ответу и потратило впустую сетевую пропускную способность. Механизм JarIndex собирает содержание всех файлов фляги, определенных в апплете, и хранит информацию в индексном файле в первом файле фляги на пути к классу апплета. После того, как первый файл фляги загружается, загрузчик класса апплета будет использовать собранную информацию контента для эффективной загрузки файлов фляги.
Существующий инструмент jar улучшается, чтобы быть в состоянии исследовать список файлов фляги и генерировать информацию о каталоге, относительно которой классы и ресурсы находятся в который файл фляги. Эта информация каталога хранится в простом текстовом файле под названием INDEX.LIST в каталоге META-INF корневого файла фляги. Когда classloader загружает корневой файл фляги, он читает файл INDEX.LIST и использует это, чтобы создать хэш-таблицу из отображений от файла и имен пакета к спискам имен файлов фляги. Чтобы найти класс или ресурс, загрузчик класса запрашивает хеш-таблицу, чтобы найти надлежащий файл фляги и затем загружает это в случае необходимости.
Как только загрузчик класса находит файл INDEX.LIST в определенном файле фляги, он всегда доверяет информации, перечисленной этому. Если отображение находится для определенного класса, но загрузчик класса не в состоянии счесть это следующим ссылкой, InvalidJarIndexException бросается. Когда это происходит, разработчик приложений должен запустить повторно инструмент jar на расширении, чтобы получить правильную информацию в индексный файл.
Чтобы предотвратить добавление слишком большого количества издержек пространства к приложению и ускорить конструкцию хэш-таблицы в памяти, файл INDEX.LIST сохраняется как можно меньше. Для классов с ненулевыми именами пакета отображения записываются на уровне пакета. Обычно одно имя пакета отображается на один файл фляги, но если определенный пакет охватит больше чем один файл фляги, то отображенное значение этого пакета будет списком файлов фляги. Для файлов ресурсов с непустыми префиксами каталога отображения также записываются на уровне каталога. Только для классов с нулевым именем пакета, и файлов ресурсов, которые находятся в корневом каталоге, будет отображение быть записанным на отдельном уровне файла.
Спецификация Индексного файла
Файл INDEX.LIST содержит один или более разделов каждый разделенный единственной пустой строкой. Каждый раздел определяет контент определенного файла фляги, с заголовком, определяющим имя пути к файлу фляги, сопровождаемое списком пакета или имен файлов, один на строку. Все пути к файлам фляги относительно кодовой базы корневого файла фляги. Эти пути разрешаются таким же образом, как текущий механизм расширения делает для связанных расширений.
Кодирование UTF-8 используется, чтобы поддерживать не символы ASCII в файле или имена пакета в индексном файле.
Спецификация
индексный файл: информация о версии blankline section* информация о версии: номер версииJarIndex-Version: номер версии: цифра + {. цифра +}* раздел: тело blankline тело: заголовок name* заголовок: новая строкаchar+.jar имя: случайная работа + новая строка случайная работа: любой допустимый символ Unicode кромеNULL, CRandLF blankline: новая строка новой строки новая строка: CR LF | LF | CR (не сопровождаемыйLF) цифра: {0-9}
Файл INDEX.LIST сгенерирован, выполняя jar -i., См. страницу справочника фляги для большего количества деталей.
Обратная совместимость
Новая схема загрузки класса полностью обратно совместима с приложениями, разработанными сверху текущего механизма расширения. Когда загрузчик класса загружает первый файл фляги, и файл INDEX.LIST находится в каталоге META-INF, это создало бы индексную хэш-таблицу и использовало бы новую схему загрузки расширения. Иначе, загрузчик класса будет просто использовать исходный линейный алгоритм поиска.
Поставщик услуг
Краткий обзор
Файлы в каталоге META-INF/services являются конфигурационными файлами поставщика услуг. Служба является известным набором интерфейсов и (обычно краткий обзор) классы. Поставщик услуг является определенной реализацией службы. Классы в провайдере обычно реализуют интерфейсы и разделяют на подклассы классы, определенные в службе непосредственно. Поставщики услуг могут быть установлены в реализации платформы Java в форме расширений, то есть, файлы фляги, помещенные в любой из обычных каталогов расширения. Провайдеры могут также быть сделаны доступными, добавляя их к апплету или пути класса приложений или некоторыми другими специфичными для платформы средствами.
Служба представляется абстрактным классом. Провайдер данной службы содержит один или более реальные классы, которые расширяют этот класс службы с помощью данных и кодируют определенный для провайдера. Этот класс провайдера обычно не будет всем провайдером непосредственно, а скорее прокси, который содержит достаточную информацию, чтобы решить, ли провайдер в состоянии удовлетворить определенный запрос вместе кодом, который может создать фактического провайдера по требованию. Детали классов провайдера имеют тенденцию быть очень специфичными для службы; никакой единый класс или интерфейс не могли возможно объединить их, таким образом, никакой такой класс не был определен. Единственное требование, осуществленное здесь, - то, что у классов провайдера должен быть конструктор нулевого параметра так, чтобы они можно было инстанцировать во время поиска.
Конфигурационный файл провайдера
Поставщик услуг идентифицирует себя, помещая конфигурационный файл провайдера в каталог META-INF/services ресурса. Имя файла должно состоять из полностью определенного имени класса реферативной службы. Файл должен содержать разделенный от новой строки список уникальных конкретных имен классов провайдера. Пространство и символы вкладки, так же как пустые строки, игнорируются. Символ комментария '#' (0x23); на каждой строке игнорируются все символы после первого символа комментария. Файл должен быть закодирован в UTF-8.
Пример
Предположите, что у нас есть класс службы, названный java.io.spi. CharCodec. У этого есть два абстрактных метода:
public abstract CharEncoder getEncoder(String encodingName);
public abstract CharDecoder getDecoder(String encodingName);
Каждый метод возвращает соответствующий объект или нуль, если это не может преобразовать данное кодирование. Типичные провайдеры CharCodec будут поддерживать больше чем одно кодирование.
Если sun.io. StandardCodec является провайдером службы CharCodec тогда, ее файл фляги содержал бы файл META-INF/services/java.io.spi.CharCodec. Этот файл содержал бы одну строку:
sun.io.StandardCodec # Standard codecs for the platform
Чтобы определить местоположение кодера для данного кодирования имени, внутренний код ввода-вывода сделал бы что-то вроде этого:
CharEncoder getEncoder(String encodingName) {
Iterator ps = Service.providers(CharCodec.class);
while (ps.hasNext()) {
CharCodec cc = (CharCodec)ps.next();
CharEncoder ce = cc.getEncoder(encodingName);
if (ce != null)
return ce;
}
return null;
}
Механизм поиска провайдера всегда выполняется в контексте защиты вызывающей стороны. Код достоверной системы должен обычно вызывать методы в этом классе изнутри привилегированного контекста защиты.