Spec-Zone .ru
спецификации, руководства, описания, API
|
Java Богатое Руководство по Интернет-приложениям > Сети> Форматы Сжатия для Сетевого Развертывания
Чтобы увеличить сервер и сетевую доступность и пропускную способность, два формата сжатия доступны развертыванию Java приложений и апплетов: gzip и Pack200. С обоими методами сжатые файлы JAR передаются по сети, и приложение получения распаковывает и восстанавливает их.
См.
Этот раздел описывает технические детали того, как веб-сервер обрабатывает сжатый файл JAR. Следующие темы затрагиваются:
С версии 5.0 SDK/JRE сжатие HTTP реализуется в Сети Java, Запускаются и Плагин Java в соответствии с RFC 2616. Поддерживаемые методы являются gzip и pack200-gzip.
Запрашивающее приложение может отправить запрос HTTP серверу, указывающему на его возможность обработать сжатые версии файла. Следующее является примером запрос HTTP, создаваемый, когда
GET http://www.example.com/DynamicTreeDemo.jar.pack.gz HTTP/1.1 accept-encoding: pack200-gzip,gzip User-Agent: Mozilla/4.0 (Windows 7 6.1) Java/1.7.0_04-ea Host: example.com Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2 Connection: keep-alive
Следующее является ответом HTTP от сервера:
HTTP/1.1 200 OK Date: Wed, 21 Mar 2012 20:13:22 GMT Server: Apache/2.2.11 (Unix) mod_ssl/2.2.11 OpenSSL/0.9.8k SVN/1.6.2 DAV/2 Last-Modified: Thu, 08 Mar 2012 03:48:34 GMT ETag: "489ee5-112d-4bab326774e43" Accept-Ranges: bytes Content-Length: 4397 Keep-Alive: timeout=5, max=99 Connection: Keep-Alive Content-Type: application/x-gzip Content-Encoding: gzip
Для получения дополнительной информации о Динамическом Древовидном Демонстрационном апплете, см.
Accept-Encoding
поле определяет то, что может принять клиент, который устанавливается клиентом. Content-Encoding
поле указывает на то, что отправляется, который устанавливается сервером. Content-Type
поле указывает на то, что должен ожидать клиент, когда преобразование или декодирование будут сделаны.
В этом примере, Accept-Encoding
поле устанавливается в pack200-gzip
и gzip
, указывая к серверу, что приложение (в этом случае, Mozilla Firefox, работающий в Windows 7 с Плагином Java, который идет с JRE 7), может обработать pack200-gzip
и gzip
форматы.
Сервер ищет требуемый файл JAR с a .pack.gz
или .gz
расширение файла и отвечает расположенным файлом. Сервер устанавливает заголовок ответа Content-Encoding
поле к pack200-gzip
, gzip
, или NULL
в зависимости от типа файла, который отправляется, и дополнительно может установить Content-Type
к application/x-java-archive
. Поэтому, осматривая Content-Encoding
поле, запрашивающее приложение может применить соответствующее преобразование, чтобы восстановить исходный файл JAR.
Пример 1: Приложение, запрашивающее упакованный или сжатый JAR
В Примере 1, клиент запрашивает файл foo.jar
с Accept-Encoding
поле pack200-gzip,gzip
. Сервер ищет файл foo.jar.pack.gz
. Если сервер найдет файл, то он отправит файл клиенту и установит Content-Encoding
поле к pack200-gzip
.
Пример 2: Приложение, запрашивающее упакованный или сжатый JAR
В Примере 2, если файл foo.jar.pack.gz
не находится, сервер отвечает файлом foo.jar.gz
, если это находится, и устанавливает Content-Encoding
поле к gzip
.
Пример 3: Приложение, запрашивающее упакованный или сжатый JAR
В Примере 3, если файлы foo.jar.pack.gz
и foo.jar.gz
не находятся, тогда сервер отвечает файлом foo.jar
и любой не устанавливает Content-Encoding
поле или наборы это к NULL
.
Пример 4: Унаследованное приложение, запрашивающее JAR
В Примере 4, унаследованное приложение (приложение без HTTP или сжатий Pack200) запрашивает файл foo.jar
; следовательно это приложение будет продолжать работать легко. Поэтому, рекомендуется, чтобы Вы разместили все три файла foo.jar
, foo.jar.gz
, и foo.jar.jar.gz
.
gzip
компрессор в свободном доступе, доступный в пределах JRE и SDK как java.util.zip.GZIPInputStream
java.util.zip.GZIPOutputStream
Версии командной строки доступны с большинством операционных систем Unix, инструментарии Windows Unix (
Можно получить самую высокую степень использования сжатия gzip
сжимать несжатый файл JAR против сжатия сжатого файла JAR. Нижняя сторона - то, что файл JAR может храниться несжатый на целевых системах.
Вот пример:
gzip
сжимать файл JAR, который содержит человека выкачанные записи: Notepad.jar
: 46.25 КбитNotepad.jar.gz
: 43.00 Кбитаgzip
сжимать файл JAR, который содержит сохраненные записи (сохраненные записи являются записями, которые не сжимаются): Notepad.jar
: 987.47 КбитNotepad.jar.gz
: 32.47 КбитаКак можно видеть, размер загрузки может быть уменьшен на 14 %, сжимая несжатый файл JAR по сравнению с 3 %, сжимая сжатый файл JAR.
Pack200 сжимает большие файлы очень эффективно, в зависимости от плотности и размера файлов class в файле JAR. Можно ожидать сжатие к одной девятой размер файла JAR, если это будет содержать только файлы class и будет в порядке нескольких мегабайтов.
Используя ту же самую флягу в предыдущем примере:
Notepad.jar
: 46.25 КбитNotepad.jar.pack.gz
: 22.58 КбитаВ этом случае тот же самый файл JAR может быть уменьшен на 50 %.
Pack200 работает наиболее эффективно над Java файлы class. Это использует несколько методов, чтобы эффективно уменьшить размер файлов JAR:
Сожмите и распакуйте файлы JAR с интерфейсами командной строки pack200
и unpack200
в bin
каталог Вашего SDK или каталог JRE.
Можно также программно вызвать интерфейсы Pack200; см. java.util.jar.Pack200
Все эти факторы играют в выбор метода сжатия. unpack200
инструмент разрабатывается, чтобы быть настолько эффективным насколько возможно, и он занимает время, чтобы восстановить исходный файл. Если у Вас есть большие файлы JAR (2 Мбайта или больше) состоявший главным образом из файлов class, Pack200 является привилегированным методом сжатия. Если у Вас есть большие файлы JAR, которые состоят из файлов ресурсов (JPEG, ДЖИФ, данные, и т.д.), то gzip является привилегированным методом сжатия.
Pack200 загружает весь сжатый файл в память. Однако, когда целевые системы являются памятью и ограниченным ресурсом, устанавливая Pack200.Packer.SEGMENT_LIMIT
к нижнему значению уменьшит требования к памяти во время сжатия и несжатия.
Как особый случай, значение -1
произведет единственный большой сегмент со всеми входными файлами, в то время как значение 0
произведет один сегмент для каждого class. Больший результат сегментов архива на меньшем количестве фрагментации и лучшее сжатие, но обработка их требуют большего количества памяти.
Значение по умолчанию -1
, что означает pack200
будет всегда создавать единственный выходной файл сегмента. В случаях, где файлы чрезвычайно крупносерийного производства сгенерированы, Вы, строго поощряются использовать сегментацию или разбить входной файл в меньшие JAR.
Например, JAR на 10 Мбайт, упакованный без этого предела, будет обычно упаковывать приблизительно на 10 % меньший, но pack200
может потребовать большей "кучи" Java (приблизительно десять раз предел сегмента).
Pack200 перестраивает содержание получающегося файла JAR. jarsigner
unpack200
распаковывает файл, содержание классов будет перестроено и таким образом лишит законной силы подпись. Поэтому, файл JAR должен быть нормализован, сначала используя pack200
и unpack200
, и после того подписанный.
Вот то, почему это работает: Любое переупорядочение pack200
делает на любых classfile структурах, идемпотент, таким образом, во второй раз он сжимается, он не изменяет упорядочивания, произведенные первым сжатием. Кроме того, unpack200
гарантируется JSR 200 спецификаций, чтобы произвести определенное изображение bytewise для любого данного упорядочивания передачи элементов архива.
Например, предположите, что Вы хотите использовать HelloWorld.jar
:
Пересжатие, или перепаковывают, файл, чтобы нормализовать флягу; перепаковывание распаковывает и сжимает файл JAR за один шаг.
% pack200 --repack HelloWorld.jar
Подпишите JAR.
% jarsigner -keystore myKeystore HelloWorld.jar user_name
Проверьте справедливый подписанный файл JAR, чтобы гарантировать работавшее подписание.
% jarsigner -verify HelloWorld.jar jar verified.
Гарантируйте, что файл JAR все еще работает.
% Java -jar HelloWorld.jar HelloWorld
Сожмите файл JAR с pack200
.
% pack200 HelloWorld.jar.pack.gz HelloWorld.jar
Распакуйте файл с unpack200
% unpack200 HelloWorld.jar.pack.gz HelloT1.jar
Проверьте файл JAR.
% jarsigner -verify HelloT1.jar jar verified.
Протестируйте флягу.
% Java -jar HelloT1.jar HelloWorld
После проверки можно развернуть сжатый файл пакета HelloWorld.jar.pack.gz
..
Pack200 по умолчанию ведет себя в Высоком качестве (Магнитофон) режим, означая, что все исходные атрибуты, существующие в классах так же как атрибутах каждой отдельной записи в файле JAR, сохраняются. Они обычно имеют тенденцию добавлять к упакованному размеру файла; вот некоторые из методов, которые можно использовать, чтобы далее уменьшить размер загрузки:
Время изменения: Если время изменения отдельных записей в файле JAR не является беспокойством, можно определить опцию Pack200.Packer.MODIFICATION_TIME="LATEST"
. Это позволит одному времени изменения быть переданным в файле пакета для каждого сегмента. Последнее время будет последним временем любой записи в пределах того сегмента.
Подсказка дефляции: Подобный установке времени изменения к "LATEST"
, если состояние сжатия отдельных записей в архиве не требуется, установить Pack200.Packer.DEFLATION_HINT="false"
. Это незначительно уменьшит размер загрузки, поскольку отдельные подсказки сжатия не будут переданы. Однако, фляга когда реконструировано будет содержать "сохраненные" записи и следовательно может использовать больше дискового пространства на целевой системе.
Например:
pack200 --modification-time=latest --deflate-hint="true" tools-md.jar.pack.gz tools.jar
Отметьте: вышеупомянутая оптимизация приведет к лучшим результатам с файлом JAR, содержащим тысячи записей.
Атрибуты: Несколько атрибутов class не требуются, развертывая файлы JAR. Эти атрибуты могут быть разделены из файлов class, значительно уменьшая размер загрузки. Однако, забота должна быть проявлена, чтобы гарантировать, что сохраняются необходимые атрибуты времени выполнения.
Отладка атрибутов: Если отладочная информация, такая как Номера строки и Исходный файл, не требуется (обычно в трассировках стека приложений), то эти атрибуты могут быть отброшены, определяя Pack200.Packer.STRIP_DEBUG=true.
Это обычно уменьшает упакованный файл приблизительно на 10 %.
Пример:
pack200 --strip-debug tools-stripped.jar.pack.gz tools.jar
Другие атрибуты: Усовершенствованные пользователи могут использовать некоторые из других связанных с полосой свойств, чтобы разделить дополнительные атрибуты. Однако, экстремальное предостережение должно использоваться, делая так, результирующий файл JAR должен быть протестирован на всех возможных системах Среды выполнения Java, чтобы гарантировать, что время выполнения не зависит от разделенных атрибутов.
Pack200 имеет дело со стандартными атрибутами, определенными Спецификацией виртуальной машины Java; однако компиляторы свободны представить пользовательские атрибуты. Когда такие атрибуты присутствуют, по умолчанию, Pack200 проходит через class, испуская предупреждающее сообщение. Они "проходили" через файлы class, может способствовать чрезмерному увеличению размера упакованных файлов. Если неизвестные атрибуты распространены в классах файла JAR, это может привести к очень большому чрезмерному увеличению размера в сжатом выводе. В таких случаях рассмотрите следующие стратегии:
Разделите атрибут, если атрибут, как считают, избыточен во времени выполнения; это может быть достигнуто, устанавливая свойство Pack200.Packer.UNKNOWN_ATTRIBUTE=STRIP
:
pack200 --unknown-attribute=strip foo.pack.gz foo.jar
Если атрибуты требуются во времени выполнения, и они действительно способствуют инфляции в размере сжатого файла, то идентифицируют атрибут из предупреждающего сообщения и применяют подходящее расположение для них как описано в Pack200 JSR 200 спецификаций, и ссылочный раздел API Java для интерфейса Pack200. Упаковщик.
Возможно, что компилятор мог определить атрибут, не реализованный в спецификации расположения Pack200, и может вызвать pack200
неправильно функционировать. В таких случаях можно "пройти" через весь файл class или файлы class, как будто это было ресурсом на основании своего имени и может быть определено следующим образом:
pack200 --pass-file="com/acme/foo/bar/baz.class" foo.pack.gz foo.jar
Следующее проходит через весь каталог и его содержание,
pack200 --pass-file="com/acme/foo/bar/" foo.pack.gz foo.jar
Отметьте: подписывая большие файлы JAR, этот шаг может перестать работать с ошибкой безопасности. Вероятной причиной является ошибка
--segment-limit=-1
во время перепаковывания и упаковки.pack200 --repack b.jar a.jar
b.jar
.pack200 --repack c.jar b.jar
c.jar
.pack200 out.jar.pack.gz c.jar
out.jar.pack.gz
.Можно хотеть использовать в своих интересах технологию Pack200 в своей программе установки, посредством чего файлам JAR продукта, возможно, понадобится к сжатому использованию Pack200 и несжатый во время установки. Если JRE или SDK связываются в установке, Вы свободны использовать unpack200
(Unix) или unpack200.exe
(Windows) инструмент в распределении bin
каталог. Эта реализация является чистым приложением C++, не требующим, чтобы никакая Среда выполнения Java присутствовала для этого, чтобы работать.
Windows: Установщики могут использовать лучший алгоритм чем тот в GZIP, чтобы сжать записи. В таких случаях каждый получит лучшее сжатие, используя внутреннее сжатие Установщика, при использовании pack200
инструмент следующим образом:
pack200 --no-gzip foo.jar.pack foo.jar
Это будет препятствовать тому, чтобы выходной файл был сжатым gzip.
unpack200
консольное приложение Windows; то есть это выведет на экран окно MS-DOS во время установки. Чтобы подавить это, используйте средство запуска с a WinMain
, который подавит это окно, как показано ниже.
Пример кода:
#include "windows.h" #include <stdio.h> int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { STARTUPINFO si; memset(&si, 0, sizeof(si)); si.cb = sizeof(si); PROCESS_INFORMATION pi; memset(&pi, 0, sizeof(pi)); //Test //lpCmdLine = "c:/build/windows-i586/bin/unpack200 -l c:/Temp/log c:/Temp/rt.pack c:/Temp/rt.jar"; int ret = CreateProcess(NULL, /* Exec. name */ lpCmdLine, /* cmd line */ NULL, /* proc. sec. attr. */ NULL, /* thread sec. attr */ TRUE, /* inherit file handle */ CREATE_NO_WINDOW | DETACHED_PROCESS, /* detach the process/suppress console */ NULL, /* env block */ NULL, /* inherit cwd */ &si, /* startup info */ &pi); /* process info */ if ( ret == 0) ExitProcess(255); // Wait until child process exits. WaitForSingleObject( pi.hProcess, INFINITE ); DWORD exit_val; // Be conservative and return if (GetExitCodeProcess(pi.hProcess, &exit_val) == 0) ExitProcess(255); ExitProcess(exit_val); // Return the error code of the child process return -1; }
Требуется, что все файлы JAR, сжали и распаковали, быть протестированными на правильность с Вашими приложениями тестируют спецификаторы. При использовании интерфейса командной строки pack200
, выходной файл будет сжат, используя gzip со значениями по умолчанию. Пользователь может создать простой файл пакета и использование сжатия gzip
с определенными пользователем опциями или использующий некоторый другой компрессор.
Для получения дополнительной информации см. pack200
и unpack200
в Инструментах Развертывания Java.
В Java SE 6, Java был обновлен формат файла class. Для получения дополнительной информации см.
Сохранить изменения минимальными и без шва для пользователей, pack200
генерирует соответственно имеющие версию файлы пакета, основанные на версии ввода файлы class.
Также, чтобы поддержать обратную совместимость, если входные файлы JAR исключительно состоят из JDK 1.5 или более старых файлов class, 1.5 совместимых файла пакета производятся. Иначе Java SE 6 совместимых файлов Pack200 производится. Для получения дополнительной информации обратитесь к pack200
В Java SE 8, Java формат файла class был обновлен из-за
В результате сжатые файлы, создаваемые с этой версией pack200
не будет совместимым с более старыми версиями unpack200
.
Вообще, если сжатый файл будет содержать Java SE 8 или Java SE 7 файлов class, то это не будет совместимым с неупаковщиками старшего возраста. (Например, если сжатый файл будет содержать Java SE 7 файлов class, то это не будет совместимым с неупаковщиками от Java SE 6 или ранее.)