Опции c И f могут появиться в любом порядке, но не должно быть никакого пространства между ними.
Эта команда генерирует сжатый файл JAR и поместит его в текущий каталог. Команда также генерирует файл манифеста значения по умолчанию для архива JAR.
Отметьте:
Можно добавить любую из этих дополнительных опций к опциям cf основной команды:
jar cmf existing-manifest jar-file input-file(s)
См. Изменение Файла манифеста для получения дополнительной информации о его опции.
Предупреждение: декларация должна закончиться новой строкой или возвратом каретки. Последняя строка не будет проанализирована должным образом, если она не закончится новой строкой или возвратом каретки.
Отметьте:
Пример
Давайте смотреть на пример. Простой апплет TicTacToe. Можно видеть исходный код этого Апплета в TicTacToe.java . Этот демонстрационный пример содержит байт-код файл class, аудиофайлы, и изображения, имеющие эту структуру:
Иерархия папок TicTacToe
audio и подкаталоги images содержат звуковые файлы и изображения ДЖИФА, используемые апплетом.
Как создать исполняемый jar файл в IntelliJ IDEA
Можно получить все эти файлы из каталога фляги/примеров, когда Вы загружаете все Учебное руководство онлайн. Чтобы упаковать этот демонстрационный пример в единственный файл JAR под названием TicTacToe.jar, Вы выполнили бы эту команду изнутри каталога TicTacToe:
jar cvf TicTacToe.jar TicTacToe.class audio images
adding: TicTacToe.class (in=3825) (out=2222) (deflated 41%) adding: audio/ (in=0) (out=0) (stored 0%) adding: audio/beep.au (in=4032) (out=3572) (deflated 11%) adding: audio/ding.au (in=2566) (out=2055) (deflated 19%) adding: audio/return.au (in=6558) (out=4401) (deflated 32%) adding: audio/yahoo1.au (in=7834) (out=6985) (deflated 10%) adding: audio/yahoo2.au (in=7463) (out=4607) (deflated 38%) adding: images/ (in=0) (out=0) (stored 0%) adding: images/cross.gif (in=157) (out=160) (deflated -1%) adding: images/not.gif (in=158) (out=161) (deflated -1%)
Можно видеть от этого вывода, что файл JAR TicTacToe.jar сжимается. Инструмент Фляги сжимает файлы по умолчанию. Можно выключить функцию сжатия при использовании 0 (нуль) опция, так, чтобы команда была бы похожа:
jar cvf0 TicTacToe.jar TicTacToe.class audio images
Вы могли бы хотеть избежать сжатия, например, увеличить скорость, которой файл JAR мог быть загружен браузером. Несжатые файлы JAR могут обычно быть загружены более быстро чем сжатые файлы, потому что от необходимости распаковать файлы во время загрузки избавляют. Однако, есть компромисс в то время загрузки по сети, может быть более длинным для больших, несжатых файлов.
Инструмент Фляги примет параметры, которые используют подстановочный знак символ *. Пока не было никаких нежелательных файлов в каталоге TicTacToe, Вы, возможно, использовали эту альтернативную команду, чтобы создать файл JAR:
jar cvf TicTacToe.jar *
Хотя многословный вывод не указывает на это, инструмент Фляги автоматически добавляет файл манифеста к архиву JAR с путем META-INF/MANIFEST.MF. См. Работу с Файлами манифеста: раздел Основ для информации о файлах манифеста.
Java. 02. Компиляция, запуск и создание JAR на примере простой программы
В вышеупомянутом примере, файлах в архиве, сохраненном их относительные пути и структура каталогов. Инструмент Фляги предоставляет возможность -C, которую можно использовать, чтобы создать файл JAR, в котором не сохраняются относительные пути заархивированных файлов. Это моделируется после опции -C TAR.
Как пример, предположите, что Вы хотели поместить аудиофайлы и изображения gif, используемые демонстрационным примером TicTacToe в файл JAR, и что Вы хотели, чтобы все файлы были на верхнем уровне без иерархии каталогов. Вы могли выполнить это, давая эту команду из родительского каталога каталогов images И audio:
jar cf ImageAudio.jar -C images . -C audio .
META-INF/MANIFEST.MF cross.gif not.gif beep.au ding.au return.au yahoo1.au yahoo2.au
В отличие от этого, предположите, что Вы использовали команду, которая не использовала опцию -C:
jar cf ImageAudio.jar images audio
У получающегося файла JAR было бы это оглавление:
META-INF/MANIFEST.MF images/cross.gif images/not.gif audio/beep.au audio/ding.au audio/return.au audio/yahoo1.au audio/yahoo2.au
Ваше использование этой страницы и всего материала на страницах под «Учебным баннером» Java подвергается этим официальным уведомлениям.
Источник: spec-zone.ru
JAR-Файлы
Для удобства распространения приложения, в Java существует такой механизм как JAR (Java Archive) файлы. JAR-файлы используются для архивации и сжатия данных.
Базовый формат команды для создания JAR-файла такой:
jar -cf jar-файл входной-файл(ы)
Сгерированный JAR-файл будет помещен в текущий каталог.
Рассмотрим ключи и аргументы, использованные в этой команде:
- Ключ c показывает, что необходимо создать (create) JAR-файл.
- Ключ f показывает, что необходимо направить вывод в файл, а не в стандартный поток вывода.
- jar-файл — это имя, которое необходимо дать результирующему JAR-файлу. Вы можете использовать любое имя для JAR-файл. По соглашению, имени JAR-файла дается расширение .jar, хотя это и необязательно.
- Аргумент входной-файл(ы) — список с разделителем пробелом из одного или более файлов, которые вы хотите поместить в ваш JAR-файл. Аргумент входной-файл(ы) может содержать также символ джокер *. Если любые из входных файлов являются каталогами, содержимое этих каталогов рекурсивно добавляется в архив JAR.
Правила относительно структуры JAR-файла.
- Команда jar автоматически создаст META-INF каталог.
- Команда jar автоматически создаст MANIFEST.MF и поместит его в META-INF каталог.
- Сохраняется точная структура каталогов.
- Команды java и javac могут использовать JAR-файл как нормальное дерево каталогов.
- Поиск JAR-файлов с помощью ключа -cp аналогичен поиску пакетных файлов. Единственная разница — путь к JAR-файлу должен содержать имя JAR-файла (например classes/project1.jar).
Рассмотрим на примере как создаются и используются JAR файлы.
Допустим, что наше приложение имеет следующую структуру каталогов:

Создадим JAR-файл project1.jar, который будет содержать пакеты first и second :
cd project1/classes jar –cf project1.jar first second
Можем просмотреть содержимое project1.jar файла с помощью следующей команды:
jar -tf project1.jar
Результат выполнения будет приблизительно такой:
META-INF/ META-INF/MANIFEST.MF first/ first/Example1.class second/ second/Example2.class
Перенесем созданный project1.jar файл в каталог lib и запустим на выполнение программу first.Example :
cd lib java -cp project1.jar first.Example1
Презентацию с видео можно скачать на Patreon .
Источник: www.examclouds.com
Создание Windows службы на Java

В рамках одного из проектов требовалось разработать Windows службу, которая могла бы выполнять ряд действий с помощью Windows API, Websocket и стандартных средств Java. Далее в статье будут описаны шаги, которые были сделаны для создания такой службы.
Потребность в Windows службе возникла из-за необходимости иметь программу со следующими возможностями:
- она должна быть постоянно запущена,
- выполнялась от системного пользователя,
- автоматически запускалась при старте системы,
- чтобы её сложно было остановить обычному пользователю.
Создание минимизированной версии JRE
Так как GraalVM всё ещё не поддерживает создание исполняемых файлов под Windows, было решено воспользоваться другими возможностями, которые предоставляет экосистема Java, а именно создание минимизированной версии JRE.
Для того, чтобы создать минимизированную версию JRE, для начала необходимо узнать зависимости на определенные пакеты, которые будут включены в JRE.
В первую очередь необходимо собрать jar-файл “fat jar” со всеми зависимостями.
Затем выполнить команду jdeps -s , чтобы получить список всех зависимостей. Например:
jdeps -s application.jar application.jar -> java.base application.jar -> java.datatransfer application.jar -> java.desktop application.jar -> java.logging application.jar -> java.net.http application.jar -> java.sql application.jar -> java.xml application.jar -> jdk.unsupported application.jar -> not found
Далее создаём нашу версию JRE с данными зависимостями:
java.base,java.datatransfer,java.desktop,java.logging,java.net.http,java.sql,java.xml,jdk.unsupported —strip-debug —compress 2 —no-header-files —no-man-pages —output
Обратите внимание, что перечисление пакетов для опции —add-modules необходимо разделять запятой и не ставить между ними пробелов. Остальные опции отвечают за сжатие и убирание файлов и другой информации, которая не пригодится для выполнения программы.
После выполнения этих действий JRE будет занимать порядка 30 mb, вместо сотен.
Создание Windows службы из любого приложения
Java не имеет стандартных средств по созданию служб, поэтому были изучены сторонние инструменты и был выбран WinSW в силу его бесплатности и простоты использования.
WinSW
WinSW — это утилита, которая позволяет запустить и обернуть любой процесс как Windows службу. Для того, чтобы начать с ней работать, необходимо скачать исполняемый и конфигурационный файлы по этой ссылке https://github.com/kohsuke/winsw/releases.
Необходимо поместить эти два файла в директорию. Переименовать исполняемый файл на своё усмотрение и дать такое же название файлу конфигурации, затем поместить в эту директорию jar-файл приложения и созданную JRE.
В конфигурационном файле необходимо прописать минимальную конфигурацию:
идентификатор службы имя Описание jrebinjava.exe -jar application.jar
jrebinjava.exe — относительный путь внутри нашей папки к исполняемому файлу нашей JRE.

После этих действий можно установить службу, для этого необходимо выполнить команду от имени администратора:
Список команд можно посмотреть здесь .
Взаимодействие Java и Windows API
Для использования функций Windows (таких как создание нового процесса или добавление ключей реестра) в нашем приложении был использован JNA.
JNA (Java Native Access) предоставляет Java-программам легкий доступ к библиотекам, написанным на другом языке, без написания чего-либо, кроме кода Java. JNA позволяет напрямую вызывать нативные функции, используя обычный вызов метода Java. Большинство методов не требуют специальной обработки или конфигурации; не требуется шаблон или сгенерированный код.
Подключить и работать с JNA очень просто, для этого необходимо скачать jar-файл или подключить зависимость в сборщик проекта — в нашем случает Maven:
net.java.dev.jna jna-platform 5.0.0
В нашем проекте мы использовали JNA для достижения следующих целей: заблокировать и сделать вновь доступным диспетчер задач 1) по комбинации Ctrl+Shift+Esc и 2) в меню, доступном по комбинации Ctrl+Alt+Del.
Для достижения этого были использованы класс Advapi32Util (удобная обёртка над библиотекой advapi32.dll) и интерфейс WinReg с полезными константами , которые предоставляют функциональность для внесения изменений в реестр Windows (Рисунок 1. Класс TaskManager с методами enable() и disable() для изменения ключей реестра диспетчера задач).

Рисунок 1. Класс TaskManager с методами enable() и disable() для изменения ключей реестра диспетчера задач.

- Создать новый процесс от имени определённого пользователя Windows. Для этого мы использовали метод CreateProcessAsUser()интерфейса Advapi32. В метод необходимо передать следующие параметры:
- hToken — дескриптор токена пользователя, для которого мы запускаем процесс.
- lpApplicationName — имя модуля, который должен быть выполнен.
- lpCommandLine — командная строка для выполнения.
- lpProcessAttributes — указатель на структуру SECURITY_ATTRIBUTES, которая определяет дескриптор безопасности для нового объекта процесса и определяет, могут ли дочерние процессы наследовать возвращенный дескриптор процесса.
- lpThreadAttributes — указатель на структуру SECURITY_ATTRIBUTES, который определяет дескриптор безопасности для нового объекта потока и определяет, могут ли дочерние процессы наследовать возвращенный дескриптор потока.Создать новый процесс от имени определённого пользователя Windows. Для этого мы использовали метод CreateProcessAsUser() интерфейса Advapi32. В метод необходимо передать следующие параметры:
- bInheritHandles — если этот параметр TRUE, каждый наследуемый дескриптор вызывающего процесса наследуется новым процессом. Если параметр FALSE, процессы не наследуются.
- dwCreationFlags — флаги, которые контролируют класс приоритета и создают процесс.
- lpEnvironment — указатель на блок среды для нового процесса. Если этот параметр равен NULL, новый процесс использует среду вызывающего процесса. Блок среды состоит из блока с нулевым завершением строк с нулевым завершением. Каждая строка имеет следующий вид: name = value 0.
- lpCurrentDirectory — полный путь к текущему каталогу для процесса. Строка также может указывать путь UNC (universal naming convention).
- lpStartupInfo — указатель на структуру STARTUPINFO или STARTUPINFOEX.lpProcessInformation — указатель на структуру PROCESS_INFORMATION, которая получает идентификационную информацию о новом процессе.
Рисунок 2. Метод для создания нового процесса для определённого пользователя Windows.
- Получить токен активного пользователя, т.к. он необходим для создания процесса от определённого пользователя.
private static final Function activeSessionFunc = Function.getFunction(«kernel32», «WTSGetActiveConsoleSessionId»); private static final Function userTokenFunc = Function.getFunction(«wtsapi32», «WTSQueryUserToken»); public static WinNT.HANDLE getActiveUserToken() < PointerByReference pointer = new PointerByReference(); WinDef.ULONG activeSessionFunc.invoke(WinDef.ULONG.class, null); userTokenFunc.invoke(WinDef.BOOL.class, new Object[]); return new WinNT.HANDLE(pointer.getValue()); >
Работа с процессами
Для работы и слежения за процессами в Windows был использован, добавленный в Java 9, класс ProcessHandle. ProcessHandle позволяет получать и производить различные манипуляции с процессами. В частности, при решении задачи, требовалось собирать PID процессов, фильтровать процессы на основе имени и принудительно завершать необходимые процессы.

Рисунок 3. Класс ProcessHandler с методами takeSnapshot() для создания снимка текущих процессов и closeNewProcesses() для завершения процессов, отличных от снимка.
Взаимодействие с другими компонентами системы
WebSocket
Для Java существует стандартизированный API для работы с WebSocket.
javax.websocket javax.websocket-api 1.1 provided
Но одного API недостаточно, поэтому для запуска кода была выбрана одна из его реализаций — Tyrus.
org.glassfish.tyrus tyrus-server 1.14 org.glassfish.tyrus tyrus-container-grizzly-server 1.14
Далее можно создать минималистичный сервер и указать обработчики (EndPoints).
var server = new Server( «localhost», 8080, «/endpoints», null, EndPoint1.class, EndPoint2.class, . ); try < server.start(); Thread.currentThread().join(); >catch (Exception e) < log.error(«Ooops! «, e); >finally
Заготовка обработчика выглядит следующим образом:
HTTP-клиент
С выпуском 11-ой версии Java в ней появился удобный HTTP-клиент, поэтому потребность в сторонних клиентах исчезла.
Для создания экземпляра клиента необходимо воспользоваться билдером. В простейшем случае:
var client = HttpClient .newBuilder() .build()
Далее необходимо создать запрос(request), например:
var request = HttpRequest.newBuilder() .uri(URI.create(«https://myserver.com»)) .timeout(Duration.ofMillis(1000)) .header(«Content-Type», «application/json») .POST(bean.toJSON()) .build();
Затем этот запрос можно использовать для отправки на сервер:
var response = client.send(closeSession(sessionId, token), HttpResponse.BodyHandlers.ofString());
Благодаря модульной организации версий Java 9 и выше, утилите WinSW, обновлённому Process API для взаимодействия с процессами операционной системы и библиотеки JNA (Java Native Access), которая предоставляет программам Java простой доступ к нативным библиотекам, мы смогли создать Windows службу с использованием языка Java, на котором была реализована и серверная часть. Что в итоге позволило не вводить в процесс разработки новый язык.
Источник: jazzteam.ru