Tooprogram.ru

Компьютерный справочник
0 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Java archive file

Java archive file

В обоих случаях (IDE или утилита jar) в архиве будет создаваться файл MANIFEST.MF. Как я уже писал — есть смысл почитать о дополнительных свойствах JAR-файлов. Т.к. в документации все очень неплохо написано, не буду заниматься переводом. Так что перейдем к следующему пункту нашего путешествия по JAR-файлам.

Подключение готовых JAR-файлов

Командная строка

Итак, я сказал, что основная функция JAR — содержать набор классов в виде class-файлов. Теперь нам надо понять, как подключать JAR-файлы к запускаемому классу, чтобы запускаемый класс мог использовать классы из JAR-файла.
Как вы уже хорошо знаете, запуск программы на Java включает запуск JVM (для Windows это файл java.exe, для Unix — java) и передача ей из командной строки имени класса, который вы собираетесь запускать. Например, для запуска класса First в пакете edu.javacourse.test надо в каталоге, внутри которого находится каталог edu/javacourse/test набрать такую команду:

Как видите, в качестве аргумента мы передали полное имя класса, который собираемся запускать. JVM кроме имени класса принимает достаточно много параметров, которые позволяют конфигурировать те или иные свойства JVM. В этой статье мы разберем очень важный элемент — CLASSPATH — который как раз и используется для подключения JAR-файлов.
Сейчас мы проделаем полный цикл создания JAR-файла и его подключения без использования IDE — я очень трепетно отношусь к умению программиста пользоваться командной строкой. Во-первых, это показывает, что вы действительно понимаете суть, во-вторых — этот навык ну просто очень полезен. Например, в том же Unix/Linux очень большое количество работы гораздо удобнее делать в командной строке, да и некоторые продукты содержат утилиты, запускаемые из командной строки. Так что займемся.
Создадим каталог JavaLesson (в принципе мы его уже создавали в разделе Основные шаги. В этом каталоге создадим стуктуру каталогов JarLib/edu/javacourse/jar. С помощью текстового редактора создадим файл SayHello.java

Структура наших каталогов должна выглядеть вот так:

Теперь время за командной строкой. Запускаем команду «cmd» (если не помните — смотрим раздел Основные шаги). Переходим в каталог JavaLesson/JarLib и в нем сначала компилируем наш файл SayHello.java вот такой командой

После успешной компиляции создаем JAR-файл с помощью команды

Если у вас все получилось, то в каталоге JavaLesson/JarLib должен появится файл say.jar.
Теперь напишем небольшой класс, который будет использовать наш класс SayHello. ВАЖНО . Для «чистоты эксперимента» создадим этот класс в каталоге JavaLesson. Предлагаю создать класс без использования пакетов (хотя это не должно быть правилом — в реальных проектах создавать классы без пакетов не надо). Вот наш файл UseHello.java, который будет находится в каталоге JavaLesson

Обратите внимание на первую строчку — в ней мы импортируем класс SayHello. В методе main мы создаем объект и вызываем его метод. Структура наших каталогов должна выглядеть вот так:

Теперь нам надо скомпилировать наш замечательный класс. Пробуем команду javac. ВНИМАНИЕ . Мы находимся в каталоге JavaLesson.

И мы получаем ошибку:

Сообщение в данном случае достаточно информативное — «UseHello.java:1: error: package edu.javacourse.jar does not exist» и «UseHello.java:6: error: cannot find symbol». Мы же не подключали наш класс SayHello — вот компилятор и не знает, откуда его брать и вообще откуда такой пакет/класс — edu.javacourse.jar.SayHello. Ну что же — перефразируя классику — «Ваше слово, товарищ CLASSPATH».
Очевидно, что нам надо компилятору подсказать, что он должен использовать не только те JAR-файлы, которые у него уже есть — тот же rt.jar — но и наш JAR-файл. Делается это с помощью специальной опции при запуске компилятора.

В этой команде мы добавили строку -cp JarLib/say.jar. Часть -cp говорит, что за ней должен идти список JAR-файлов, которые содержат нужные классы. Список может включать несколько файлов, разделенных для Windows знаком «;», для Unix/Linux — «:». Например, если мне надо указать два файла — say1.jar и say2.jar — находящихся в каталоге C:/Anton/Libraries, то команда (для Windows) выглядела бы так:

Кстати, «-cp» — сокращенно от classpath — раньше надо было писать именно так, да и сейчас тоже можно.

Также важно отметить, что в CLASSPATH можно включать не только JAR-файлы — туда можно включать путь до каталога с файлами .class (опять же — их может быть указано несколько штук). Если бы мы не создавали JAR-файл say.jar, а использовали скомпилированный файл SayHello.class из каталога JarLib, то команда выглядела бы вот так:

Вы можете спросить — почему мы указали путь только до JarLib, а не полностью каталог с файлом SayHello.class. Дело в том, что т.к. наш файл содержится в пакете, то нам надо указать путь именно до пакета, а он находится в каталоге JarLib. Можно указать полный (а не относительный) путь — вот так:

Ну что же, скомпилировать нам удалось, самое время запускать наше замечательный класс. Скорее всего, вы уже догадываетесь, что при запуске нам тоже надо указать наш файл say.jar и выглядеть команда должна как-то так. ВНИМАНИЕ . Мы находимся в каталоге JavaLesson.

Но при запуске этой программы нас постигает неудача. Вот такое сообщение выдает JVM:

JVM не может найти наш класс. Как это, вот же он, прямо в этой директории ? Хитрость в том, что когда вы указываете CLASSPATH в командной строке, то JVM берет классы ТОЛЬКО из этих файлов/каталогов. А наш файл с классом UseHello находится в ТЕКУЩЕМ каталоге, который НЕ УКАЗАН. Вот такая вот эпидерсия. Нам надо указать JVM, чтобы она брала файлы и из текущего каталога тоже. Делается это так — в CLASSPATH надо указать символ «.». Это и будет текущий каталог. Наща команда должна выглядеть вот так:

Читать еще:  Зачем нужна java 8

Ну что же — теперь все должно получится и мы увидим надпись HELLO.
Фокус с CLASSPATH может сыграть с вами достаточно злую шутку. Дело в том, что JVM использует переменную среды, которая так и называется «CLASSPATH». Для Windows она устанавливается точно так же как переменные «PATH» и «JAVA_HOME» — мы делали это в разделе Установка JDK. В этой переменной указывается набор JAR-файлов и каталогов, которые JVM будет использовать в случае, если вы НЕ указываете CLASSPATH при запуске своей программы.
Некоторые программы при своей установке создают (или обновляют) переменную среды «CLASSPATH» и могут даже вам ничего не сказать. И вот вы из командной строки запускаете свой класс, а JVM его НЕ ВИДИТ. Потому? что она dpzkf переменную «CLASSPATH» и в ней нет символа «.». В этом случае происходит то, что мы уже видели — файлы из текущего каталога не загружаются. Так что будьте внимательны.

Подключение JAR-библиотек в IDE NetBeans

Т.к. в данном курсе я использую для демонстрации NetBeans, то наверно будет неправильно не показать, как подлкючать JAR в этой среде. Как я уже упоминал, если появится время на другие IDE, я буду писать их в этой же статье. Но не думаю, что это будет в ближащее время.
Если вы посмотрите служебное окно «Projects», которое обычно находится слева, то вы в нем вы можете увидеть структуру вашего проекта, которая содержит раздел «Libraries». Я создал два проекта SayHello и UseHello

В открытом файле UseHello.java в самой первой строке видно, что компилятор выдает в ней ошибку — как мы уже знаем, она говорит об отсутствии нужного класса. В принципе IDE позволяют подключать не только готовые JAR-файлы, но и проекты, но мы не будем использовать эту функцию (в данном случае специально). Чтобы подключить библиотеку из проекта SayHello нам для начала надо собрать этот проект через команду «Build». Результат можем увидеть в каталоге dist. В нем мы можем увидеть файл SayHello.jar. Предвидя вопрос — а можно поменять имя файла — для того, чтобы файл создавался с другим именем, надо исправлять конфигурационный файл nbproject/project.properties. Найти в нем опцию с именем dist.jar И поменять имя файла. В общем не очень удобно. Так что я обычно этого не делаю.
Теперь нам надо подключить готовый JAR-файл к нашему второму проекту UseHello. Сделать это можно несколькими способами.

  1. Щелкнуть правой кнопкой мышки на пункте «Libraries» в структуре проекта и в нем выбрать пункт «Add JAR/Folder». После выбора файла его можно будет видеть под веткой «Libraries»
  2. Целкнуть правой кнопкой мышки на проекте UseHello в окне «Projects» и в выпадающем меню выбрать пункт (обычно самый нижний) «Properties». В открывшемся диалоговом окне выбрать слева пункт «Libraries» и в закладке «Compile» использовать кнопку «Add JAR/Folder».


Также предлагаю заглянуть на закладку «Run». В нем можно увидеть, что при запуске будет подключаться те библиотеки, которые подключаются при компиляции исходников («Classpath for Compiling Source»).

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

Исходный код для проектов под NetBeans можно скачать здесь. Библиотеку в них надо подключить самостоятельно. Так что можете потренироваться. Удачи.

И теперь нас ждет следующая статья: Многопоточность — первые шаги.

Creating zip archive in Java

I have one file created by 7zip program. I used deflate method to compress it. Now I want to create the same archive (with the same MD5sum) in java . When I create zip file, I used the algorithm that I found on the Internet for example http://www.kodejava.org/examples/119.html but when I created zip file with this method the compressed size is higher than size of the uncompressed file so what is going on? This isn’t a very useful compression. So how I can create zip file that is exactly same as zip file that I created with 7zip program ? If it helps I have all information about zip file that I created in 7zip program.

7 Answers 7

Just to clarify, you used the ZIP algorithm in 7zip for your original? Also 7zip claims to have a 2-10% better compression ratio than other vendors. I would venture a guess that the ZIP algorithm built into Java is not nearly as optimized as the one in 7zip. Your best best is to invoke 7zip from the command line if you want a similarly compressed file.

Are you trying to unpack a ZIP file, change a file within it, then re-compress it so that it has the same MD5 hash? Hashes are meant to prevent you from doing that.

ZipOutputStream has few methods to tune compression:

Sets the default compression method for subsequent entries. This default will be used whenever the compression method is not specified for an individual ZIP file entry, and is initially set to DEFLATED.

Sets the compression level for subsequent entries which are DEFLATED. The default setting is DEFAULT_COMPRESSION. level — the compression level (0-9)

When you add after something like:

does not it improve your compression?

Here is a function that you pass the absolute path it will create a zip file with the same name as the directory (under which you want zip of all the sub folder and files, everything !!) and return true on success and false on exception if any.

Читать еще:  Java как запустить

To generate two identical zip files (including identical md5sum) from the same source file, I would recommend using the same zip utility — either always use the same Java program, or always use 7zip.

The 7zip utility for instance has a lot of options — many of which are simply defaults that can be customized (or differ between releases?) — and any Java zip implementation would have to also set these options explicitly. If your Java app can simply invoke an external «7z» program, you’ll probably get better performance anyway that a custom Java zip implementation. (This is also a good example of a map-reduce problem where you can easily scale out the implementation.)

But the main issue you will run into if you have a server-side generated zip file and a client-side generated zip file is that the zip file stores two things in addition to just the original file: (1) the file name, and (2) the file timestamp. If either of these have changed, then the resulting zip file will have a different md5sum:

But, using «cp -p» (preserve timestamp):

You’ll find the same problem with differing filenames and paths, even when the files inside the zip are identical.

Работа с архивами Zip и 7z

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

Согласно требованиям Google Play, apk-файл приложения должен быть не более 50 МБ, так же можно прикрепить два файла дополнения .obb по 2 гигабайта. Механизм простой, но сложный при эксплуатации, поэтому лучше всего уложиться в 50 МБ и возрадоваться. И в этом нам помогут целых два архивных формата Zip и 7z.

Давайте рассмотрим их работу на примере уже готового тестового приложения ZipExample.

Для тестов была создана sqlite база данных test_data.db. Она содержит 2 таблицы android_metadata — по традиции и my_test_data с миллионом строчек:

Размер полученного файла составляет 198 МБ.

Сделаем два архива test_data.zip (10.1 МБ) и test_data.7z (3.05 МБ).

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

Внешний вид программы представляет собой окно с текстом и двумя кнопками:

Вот метод распаковки zip архива:

Распаковывающим классом тут является ZipInputStream он входит в пакет java.util.zip, а тот в свою очередь в стандартную Android SDK и поэтому работает «из коробки» т.е. ничего отдельно закачивать не надо.

Вот метод распаковки 7z архива:

Сначала мы копируем файл архива из asserts , а потом разархивируем при помощи SevenZFile . Он находится в пакете org.apache.commons.compress.archivers.sevenz; и поэтому перед его использованием нужно прописать в build.gradle зависимость: compile ‘org.apache.commons:commons-compress:1.8’.
Android Stuodio сама скачает библиотеки, а если они устарели, то подскажет о наличии обновления.

Вот экран работающего приложения:

Размер отладочной версии приложения получился 6,8 МБ.
А вот его размер в устройстве после распаковки:

Внимание вопрос кто в черном ящике что в кеше?

В заключении хочу сказать, что распаковка архивов занимает продолжительное время и поэтому нельзя его делать в основном (UI) потоке. Это приведет к подвисанию интерфейса. Во избежание этого можно задействовать AsyncTask , а лучше фоновый сервис т.к. пользователь может не дождаться распаковки и выйти, а вы получите ошибку (правда если не поставите костылей в методе onPostExecute).

Буду рад конструктивной критике в комментариях.

Создание и использование архивов Java

Зачем нужны JAR-архивы?

Использование JAR-архивов предоставляет разработчикам аплетов (а также и автономных приложений) ряд преимуществ.

  • Повышение эффективности загрузки. Вместо нескольких файлов отдельных классов загружается единственный файл JAR-архива.
  • Улучшенное хранилище файлов, так как файлы классов хранятся в одном сжатом файле архива.
  • Повышение защищённости. В JAR-файл можно поместить цифровую подпись, дающею конечному пользователю гарантии, что файл архива не изменился с момента её внесения. Если конечный пользователь доверяет вашей фирме, он может предоставить подписанным вами аплетам право доступа к его жестким дискам или другим важным ресурсам системы.
  • Независимость от платформы. Построение JAR-архивов базируется на использовании популярной программы PKZIP сжатия файлов. Однако JAR-файлы могут создаваться и сохраняться на любой компьютерной платформе.
  • Расширяемость. В спецификацию JAR-файлов внесены некоторые дополнения, обеспечивающие возможность дальнейших расширений.

Одно только повышение эффективности загрузки даёт какое преимущество! Если вы знакомы с работой протокола HTTP, то должны понимать насколько неэффективно, с его помощью, выполнять передачу нескольких небольших файлов. В каждом случае потребуется установить новое соединение TCP/IP, которое после передачи данного файла будет разорвано. Установка каждого соединения связана с дополнительной нагрузкой на сервер и сеть. При использовании коммутируемых линий связи среднее время установки TCP/IP-соединения может составлять около 0,5 c. Если для работы аплета необходимо 16 файлов, общее время затрачиваемое только на установку соединений — 8 с.

Создание JAR-архива

Для создания и модификации JAR-архивов можно использовать любую поддерживающую формат PKZIP программу. JAR-файл отличается от zip-файла наличием дополнительного текстового файла, называемого файлом описания (manifest file). Этот файл содержит сведения обо всех помещённых в данный архив файлах. В состав файла описания должны входить определённые элементы, в частности он должен включать следующие.

  • Номер версии стандарта JAR. В соответствии, с которым построен данный архив. Этот номер задаётся параметром Manifest-Version и является обязательным. В SDK 1.2 значение этого параметра должно быть равно 1.0
  • Минимальный номер версии утилиты JAR, которая сможет прочитать этот архив. Этот параметр необязателен и имеет название Required-Version.
  • Отдельная запись для любого, помещённого в архив файла. Необязательно перечислять все помещённые в архив файлы, достаточно указать только файлы главных классов.
Читать еще:  Что такое java 7 update

Фирма Sun предоставила, для создания JAR архивов, специализированный инструмент для всех поддерживаемых платформ. Рассмотрим создание JAR-архива с помощью этой утилиты под названием jar.

Предположим, что у нас имеется каталог, содержащий несколько файлов типа .class и подкаталог с именем images содержащий несколько файлов типа .gif. Пусть имя создаваемого архива будет archive.jar

Общий формат команды вызова утилиты jar: jar параметры имена_файлов

Параметр имена_файлов представляет собой список имён файлов, первым в котором всегда указывается имя самого архивного файла. Назначение остальных имён файлов зависит от ключей:

c — создать новый архив. m — использовать внешний файл описания, имя которого указано вторым в списке имена_файлов. M — не создавать файл описания. t — вывести содержание указанного архивного. x — извлечь файлы, указанные в списке имена_файлов. Если имена не указаны, то извлечь все файлы. f — указывает, что имя архивного файла помещено первым в списке имена_файлов. v — указывает, что утилита должна сопровождать сообщениями выполнение всех действий, заданных другими параметрами. 0 — сохранение файлов в архиве выполняется без их сжатия. u — указывает, что нужно обновить указанные файлы. Или в случае команды jar umf manifest имя_архива указывает что нужно обновить информацию в файле описания. -i — указывает, что необходимо сгенерировать файл INDEX.LIST содержащий информацию о всех файлах архива.

И так для создания нового архива введите:
jar cf archive.jar .class images/.gif

Помещение в JAR-архив цифровой подписи

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

Для внесения цифровой подписи в JAR-архив необходимо иметь два инструмента.

  • Утилита keytool. Используется для генерации пары открытого и закрытого ключа и сертификата.
  • Утилита jarsigner. Используется для непосредственного помещения цифровой подписи в JAR-архивы с применением имеющегося сертификата.

Что нам понадобится:

  1. Выполнить генерацию пары ключей.
  2. Получить сертификат на эту пару.
  3. Использовать сертификат для помещения цифровой подписи в JAR-архив.

Генерация пары ключей

Для генерации новой пары ключей можно использовать следующею команду:
keytool -genkey -alias testkey

В результате выполнения этой команды будет создана новая пара ключей сохранённая в базе данных под именем testkey. Вот что у нас получится:

Программа keytool позволяет указывать следующие параметры:

-v — запрос вывода сообщений о действии программы. -alias псевдоним — псевдоним (имя) который присваивается этой паре. -keyalg алгоритм_ключа — алгоритм шифрования вашей подписи — обычно по умолчанию это алгоритм SHA1 with DSA и его можно не указывать если не собираетесь изменять его, размер ключа при генерации DSA ключевой пары может быть от 512 до 1024 бит, но если вы хотите применить MD5 with RSA то укажите опцию -keyalg «RSA» Следует заметить что опция -keyalg обуславливает и опцию -sigalg — алгоритм подписи который будет использован по умолчанию для подписания jar-файла (при создании дайджестов сообщений). -keysize длина_ключа — размер генерируемых ключей в битах. -keypass пароль — пароль для данного ключа. Если пароль не будет указан в командной строке, программа предложит ввести его значение в режиме диалога. Длина пароля должна быть не менее шести символов. -keystore хранилище — расположение хранилища ключей. -storepass пароль — пароль доступа к хранилищу ключей. -validity valDays — срок годности вашего сертификата. По умолчанию это 180 дней, можно указать больше или меньше.

По умолчанию утилита keytool помещает открытый ключ в подписанный вами же сертификат X.509.v1.

Командой keytool -list мы можем посмотреть содержимое keystore:

Получение сертификата

После генерации новой пары ключей необходимо выполнить генерацию запроса CSR (Certificate Signing Request). Этот запрос отсылается в любую выбранную службу сертификации.

Для генерации CSR запроса введите следующею команду:
keytool -certreq

Для нашей пары ключей testkey команда будет выглядеть следующим образом:
keytool -certreq -alias testkey

При генерации CSR запроса допускаются следующие параметры:

-v — сопровождение работы программы выдачей сообщений. -alias псевдоним — определение псевдонима пары ключей, для которых необходимо получить сертификат. По умолчанию применяется значение mekey. -sigalg алгоритм_сигнатуры — задание используемого алгоритма внесения подписи. -file csr_файл — имя и расположение файла, в котором помещается генерируемый запрос. -keypass пароль — пароль для доступа к данному ключу. -storepass пароль — пароль доступа к хранилищу ключей. -keystore хранилище — имя и расположения файла с парой ключей.

Сгенерированный CSR-запрос отсылается в выбранную службу сертификации. После проведения всех необходимых проверок и удостоверения вашей личности вам будет выдан требуемый сертификат.

В любом случае самостоятельно занесите полученный сертификат в файл и введите следующею команду:
keytool -import

Следующие параметры могут быть указаны в режиме import:

-v — сопровождение работы программы выдачей сообщений. -alias псевдоним — псевдоним полного имени, которое будет использоваться с данным сертификатом. -file файл-сертификата — имя и расположение файла, в котором сохранён полученный сертификат.

Команда:
keytool -export -alias testkey -file имя_файла
даст указание утилите скопировать ваш сертификат в указанный файл. Отправьте свой сертификат всем получателям, которые будут использовать подписанные вами JAR-архива.

Помещение в JAR-архив цифровой подписи с помощью утилиты jarsigner

Помимо помещения цифровой подписи в JAR-архивы утилита jarsigner способна также проверять целостность подписанных JAR-архивов. Для этого достаточно запустить её с параметром -verify/

Ссылка на основную публикацию
Adblock
detector