Как сделать java приложение для windows
Перейти к содержимому

Как сделать java приложение для windows

  • автор:

запуск Java приложений как exe файлы

Сегодня я расскажу, как запускать java приложения в виде exe файлов.
Как известно java приложения поставляются в виде jar файлов, которые не являются исполняемыми файлами, а представляют собой специальные файлы с набором инструкций для виртуальной Java машины.
Но не об этом речь. В первую очерь зачем это нужно. Я столкнулся с этой необходимостью, когда использовал любимый редактор jEdit. Захотелось связать php файлы c данным редактором, однако связать с jar файлом не представляется возможным. Также необходимость возникает, когда нужно привязать какую-либо программу с контекстным меню или, например, вызывать редактор как стандартный редактор в браузере.

  1. Качаем программу Janel
  2. Распаковываем JanelWindows.exe, JanelWindows.lap, msvcr71.dll в C:\Program Files\Janel\
  3. Переименовываем
    JanelWindows.exe в ИМЯ_ВАШЕГО_ПРИЛОЖЕНИЯ.exe,
    JanelWindows.lap в ИМЯ_ВАШЕГО_ПРИЛОЖЕНИЯ.lap
  4. Редактируем lap файл:
    • в -Djava.class.path прописываем путь к jar файлу
    • в janel.main.class название основного класса
    • в janel.main.argument агрумент вызова

    На примере jEdit:

-Djava.class.path=C:\Program Files (x86)\jEdit\jedit.jar
janel.main.class=org.gjt.sp.jedit.jEdit
janel.main.argument=-reuseview

Если необходимо привязать несколько exe приложений, просто скопируйте JanelWindows.exe и JanelWindows.lap, и настройте отдельно.

Как сделать java приложение для windows

Итак, после установки JDK создадим первое приложение на языке Java. Что необходимо для создания программы на Java? Прежде всего нам надо написать код программы, и для этого нужен текстовый редактор. Можно использовать любой текстовый редактор, например, Notepad++.

И чтобы превратить код программы в исполняемое приложение необходим компилятор. После установки JDK все файлы по умолчанию помещаются в каталог C:\Program Files\Java\jdk-[номер_версии] (при использовании ОС Windows). В моем случае это каталог C:\Program Files\Java\jdk-19 . Если мы откроем в нем подкаталог bin , то мы сможем увидеть в нем ряд утилит. Нас прежде всего интересует утилита компилятора javac . Чтобы скомпилировать класс программы, нам надо передать ее код этому компилятору.

Компилятор javac в Java

Также следует отметить другую утилиту из этой папки — java.exe, которая позволяет запускать скомпилированную программу.

Итак, создадим на жестком диске какой-нибудь каталог, в котором будут располагаться файлы с исходным кодом на языке Java. Допустим, это будет каталог C:/Java . Затем создадим в этом каталоге текстовый файл, который переименуем в Program.java . Откроем этот файл в любом текстовом редакторе и наберем в нем следующую программу:

public class Program < public static void main (String args[])< System.out.println("Hello Java!"); >>

Java является объектно-ориентированным языком, поэтому вся программа представляется в виде набора взаимодействующих классов. В данном случае определен один класс Program.

При определении класса вначале идет модификатор доступа public , который указывает, что данный класс будет доступен всем, то есть мы сможем его запустить из командной строки. Далее идет ключевое слово class , а затем название класса. То есть класс называется Program. После названия в фигурных скобках расположено содержимое класса.

Класс может содержать различные переменные и методы. В данном случае у нас объявлен один метод main . Это главный метод в любой программе на Java, он является входной точкой программы и с него начинается все управление. Он обязательно должен присутствовать в программе.

Метод main также имеет модификатор public . Слово static указывает, что метод main — статический, а слово void — что он не возвращает никакого значения. Позже мы подробнее разберем, что все это значит.

Далее в скобках у нас идут параметры метода — String args[] — это массив args, который хранит значения типа String , то есть строки. В данном случае ни нам пока не нужны, но в реальной программе это те строковые параметры, которые передаются при запуске программы из командной строки.

После списка параметров в фигурных скобках идет тело метода — это собственно те инструкции, которые и будет выполнять метод. В данном случае фактически определени определена только одна инструкция — вывод на консоль некоторой строки. Для вывода на консоль используется встроенный метод System.out.println() . В этот метод передается выводимая строка. Каждая инструкция завершается точкой с запятой.

Теперь скомпилируем написанную программу. Откроем командную строку (в Windows) или терминал в Linux/MacOS и введем там соответствующие команды. Первым делом перейдем в каталог, где лежит наш файл с программой с помощью команды:

cd C:\Java

В данном случае файл находится в каталоге C:\Java.

Первая программа на Java 16

Затем cкомпилируем программу с помощью команды

C:\Java>"C:\Program Files\Java\jdk-19\bin\javac" Program.java

Обратите внимание, что весь путь к компилятору javac берется в кавычки, а затем через пробел идет название нашего файла, который содержит класс программы.

После этого программа компилируется в байт-код, и в каталоге C:\Java можно будет найти новый файл Program.class . Это и будет файл с байт-кодом программы. Теперь нам надо его запустить с помощью утилиты java:

C:\Java>"C:\Program Files\Java\jdk-19\bin\java" Program

Здесь уже расширение у файла не надо использовать.

Для ОС Windows весь процесс будет выглядеть следующим образом:

Первая программа на Java

Добавление java в переменную Path

Для компиляции приходится вводить полный путь к комилятору javac, что может быть сопряжено с ошибками при вводе, да и каждый раз вводить полный путь тоже неудобно. Чтобы в дальнейшем облегчить работу, добавим путь к JDK в переменную PATH в переменных среды. Если мы работаем в Windows, то для добавления переменной среды через поиск найдем найдем параметр Изменение системных переменных среды . Для этого введем в поле поиска «Изменение системных переменных среды»:

Переменные среды в Windows

Выберем пункт Изменение системных переменных среды . И сначала нам откроется окно «Свойства системы», где нажмем на кнопку Переменные среды :

Системные переменные среды в Windows

Затем нам откроется окно, где мы можем увидеть все переменные среды. (Также можно перейти через Параметры и пункт Система ->Дополнительные параметры системы ->Переменные среды )

Здесь нам нужно исправить системную переменную Path . Для этого выделим ее и нажмем на кнопку «Изменить»:

Установка системной переменной пути к JDK в Windows

В эту переменную Path нам надо добавить путь к инструментам JDK. И тут есть два момента. Во-первых, при установке jdk по умолчанию ряд утилит также устанавливаются в папку C:\Program Files\Common Files\Oracle\Java\javapath . В том числе это такие файлы как java.exe и javac.exe. И путь к этой папке по умолчанию добавляется в перемнную Path. То есть мы можем использовать этот путь.

Второй момент — в последних сборках Windows компания Microsoft также устанавливает свои сборки JDK, точнее OpenJDK, которые также по умолчанию добавляются в переменную Path и которые мы также можем использовать. Но у этих сборок есть большой минус — они применяют одну из прошлых версий JDK (обычно это LTS-сборки). Например, в моем случае это 11-я версия, но текущая версия может отличаться (например, на написание данной статьи текущей являлась версия 19).

Чтобы использовать последнюю версию среди путей в переменной Path убедимся, что путь C:\Program Files\Common Files\Oracle\Java\javapath располагается выше путей к сборкам JDK от Microsoft. Для перемещения определенного пути вверх среди переменных среды можно использовать кнопку «Вверх:

Установка системной переменной пути к JDK в Windows и сборки OpenJDK от Microsoft

Также можно напрямую использовать путь к JDK.

Установка системной переменной пути к JDK в Windows и сборки OpenJDK от Microsoft

Для создания новой переменной надо нажать на кнопку «Создать» и ввести в новое поле путь «C:\Program Files\Java\jdk-[номер_версии]\bin». Но опять же его следуется с помощью кнопки Вверх поместить над путями к OpenJDK от Microsoft.

После установки переменной Path перейдем к командной строке/терминалу (в более старых версиях Windows может потребоваться перезауск командной строки) и для проверки версии введем команду

java -version

Консоль нам должна в ответ ввести номер только что установленной версии JDK (в моем случае 19-й версии):

java version "19.0.1" 2022-10-18 Java(TM) SE Runtime Environment (build 19.0.1+10-21) Java HotSpot(TM) 64-Bit Server VM (build 19.0.1+10-21, mixed mode, sharing)

И после этого можно вводить только названия утилит без полных путей:

Как написать программу для Windows на Java в Intellij Idea?

Давным давно писал программы под Windows на Delphi.
Теперь пишу для Андроид в Intellij Idea.
Как создать проект чтобы выполнялось в Windows?

  • Вопрос задан более трёх лет назад
  • 8133 просмотра

Комментировать
Решения вопроса 1

ох. в java вы создаёте приложения для исполнения в JVM. В этом есть своя кроссплатформенность, ибо где будет JVM, там вы и сможете запустить ваша приложение

при разработке на java в конечном итоге получится jar файл, который можно запустить на пк с установленной java (на windows, linux, mac. где хотите) командой
java -jar programm.jar
где programm.jar — ваше приложение.

Так же есть конвертеры а-ля java2exe, но их работоспособность проверять не доводилось.

Ответ написан более трёх лет назад
Комментировать
Нравится Комментировать
Ответы на вопрос 2

silverhawk90

Виталий @silverhawk90
Серверный Java Developer

Ваш вопрос не корректно поставлен. Он похож на: Летели два верблюда — один рыжий, другой налево, сколько весит килограмм асфальта, если ежику 24 года?

Создание 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

Заготовка обработчика выглядит следующим образом:

@ServerEndpoint(value = "endpoint/url") public class SampleEndpoint < @OnOpen public void onOpen(Session session) throws IOException < // Вызывается при инициализации нового соединения >@OnMessage public void onMessage(Session session, Message message) throws IOException < // Вызывается при получении сообщения от клиента >@OnClose public void onClose(Session session) throws IOException < // Вызывается при закрытии соединения >@OnError public void onError(Session session, Throwable throwable) < // Вызывается при возникновении ошибок >>

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, на котором была реализована и серверная часть. Что в итоге позволило не вводить в процесс разработки новый язык.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *