Как запустить jar файл в windows 10 как службу

Доброе время суток!

Задача состоит в том, чтобы запустить jar как windows службу. Для этого использую prunsrv.exe от Apache (commons.apache.org/proper/commons-daemon/procrun.html). Проблема состоит в том, что при использовании режима Java я натыкаюсь на проблему «Область данных, переданная по системному вызову, слишком мала.» Помогите понять в чем конкретно проблема и исправить ее.

Вот опции, передающиеся в prunsrv.exe

set OPTIONS=—JvmOptions=-Xss4M;-Xmx512M;-Xms256M;-Dbasedir=»%HOME%»;-Dapp.home=»%HOME%»;-Dapp.name=»jService»;-Dsun.net.inetaddr.ttl=90;-XX:+HeapDumpOnOutOfMemoryError;-XX:HeapDumpPath=»%JSERVICE_HEAP_LOG%» ^
—StartMode=Java —StartClass=com.inet.jservice.WebSocketCryptographyDaemonController —StartParams=»start» —StartMethod=main —StopMode=Java —StopClass=com.inet.jservice.WebSocketCryptographyDaemonController —StopParams=»stop» —StopMethod=main ^
—LogPath=»%LOG_HOME%» —PidFile=»%PID_FILE%» —StdOutput=»%PRUNOUT_LOG%» —StdError=»%PRUNERR_LOG%» —LogLevel=Debug ^
—Startup=auto —Classpath=»%JSERVICE_PATH%» —Description=»123″

Затем

«.\prunsrv.exe» //IS//»jService» %OPTIONS%
«.\prunsrv.exe» //ES//»jService»

Логи prunsrv

[2016-05-02 10:11:03] [debug] ( prunsrv.c:1679) [ 4328] Commons Daemon procrun log initialized
[2016-05-02 10:11:03] [info] ( prunsrv.c:1683) [ 4328] Commons Daemon procrun (1.0.15.0 32-bit) started
[2016-05-02 10:11:03] [debug] ( prunsrv.c:561 ) [ 4328] Installing service…
[2016-05-02 10:11:03] [info] ( prunsrv.c:600 ) [ 4328] Service jService name
[2016-05-02 10:11:03] [debug] ( prunsrv.c:616 ) [ 4328] Setting service description Cryptography web socket service,Inet Company Ltd.,2016
[2016-05-02 10:11:03] [info] ( prunsrv.c:634 ) [ 4328] Service ‘jService’ installed
[2016-05-02 10:11:03] [info] ( prunsrv.c:1764) [ 4328] Commons Daemon procrun finished
[2016-05-02 10:11:03] [debug] ( prunsrv.c:1679) [ 6580] Commons Daemon procrun log initialized
[2016-05-02 10:11:03] [info] ( prunsrv.c:1683) [ 6580] Commons Daemon procrun (1.0.15.0 32-bit) started
[2016-05-02 10:11:03] [info] ( prunsrv.c:725 ) [ 6580] Starting service ‘jService’ …
[2016-05-02 10:11:03] [debug] ( prunsrv.c:1679) [ 2916] Commons Daemon procrun log initialized
[2016-05-02 10:11:03] [info] ( prunsrv.c:1683) [ 2916] Commons Daemon procrun (1.0.15.0 32-bit) started
[2016-05-02 10:11:03] [info] ( prunsrv.c:1596) [ 2916] Running ‘jService’ Service…
[2016-05-02 10:11:03] [debug] ( prunsrv.c:1374) [ 2572] Inside ServiceMain…
[2016-05-02 10:11:03] [debug] ( prunsrv.c:844 ) [ 2572] reportServiceStatusE: 2, 0, 3000, 0
[2016-05-02 10:11:03] [info] ( prunsrv.c:1127) [ 2572] Starting service…
[2016-05-02 10:11:05] [error] ( prunsrv.c:746 ) [ 6580] Failed to start ‘jService’ service
[2016-05-02 10:11:05] [error] ( prunsrv.c:746 ) [ 6580] Область данных, переданная по системному вызову, слишком мала.
[2016-05-02 10:11:05] [info] ( prunsrv.c:754 ) [ 6580] Start service finished.
[2016-05-02 10:11:05] [error] ( prunsrv.c:1755) [ 6580] Commons Daemon procrun failed with exit value: 5 (Failed to start service)
[2016-05-02 10:11:05] [error] ( prunsrv.c:1755) [ 6580] Область данных, переданная по системному вызову, слишком мала.

Не передаются какие-то параметры в prunsrv.exe? Используется не та JRE? Или нужна JDK?

In this blog post, I show you how to install a Java application with WinSW as a Windows service.
WinSW is an executable binary, which can be used to wrap and manage any custom process as a Windows service.

Demo ¶

First, we need a demo application. I will use a simple Quarkus application for this purpose.
You can install any Java application as a service. Usually, you install applications that run continuously, like an HTTP server in this case.

To bootstrap a Quarkus application, run this command:

mvn io.quarkus:quarkus-maven-plugin:2.5.1.Final:create -DprojectGroupId=com.testlab -DprojectArtifactId=testservice -DclassName="com.testlab.testservice.GreetingResource" -Dpath="/hello"
cd testservice

We will use the application as is, with just a small change. I want to create a fat JAR, a JAR with all dependent libraries included.
You can package your application in any way you want. In this case, I prefer the fat JAR installation because I only have to copy one file.

Open src\main\resources\application.properties and insert the following property:

quarkus.package.type=uber-jar

Now you can package the application with .\mvnw.cmd package. You will find the JAR
in the target folder: testservice-1.0.0-SNAPSHOT-runner.jar.

Preparation ¶

You can proceed in different ways. I usually create a new folder where I copy all the files needed to
run the application as a service. Copy the JAR from the target folder into this directory.

Java ¶

Next, I download the Java Runtime and also copy it into this folder. This is optional. Your service can access
a globally installed Java. But I prefer to have everything contained in one folder and not have to worry about someone updating
or removing the globally installed Java.

I usually download Java from Adoptium. On the release page, you will find the ZIP file with the JDK for Windows.

Download the ZIP file and unzip it into the install folder. I unzip it into the java subfolder, so the java.exe
is accessible with this path java\bin\java.exe.

WinSW ¶

Open the release page of the WinSW project and download the executable suitable for your platform.
https://github.com/winsw/winsw/releases

For this demo installation, I will download WinSW.NET461.exe. WinSW runs on Windows with .NET Framework 2.0, 4.0, or 4.6.1. If you need to install
the service on a Windows system without the .NET framework, download the core variant WinSW-x64.exe for 64-bit or WinSW-x86.exe for 32-bit systems.

Copy the executable into the folder where your JAR resides. Rename the WinSW executable to any name you like.
For this example, I will rename it to testservice.exe. Create an XML file with the same base name: testservice.xml.
Make sure that the EXE and XML files are located in the same folder.

Open the XML file and paste the following code into it:

<service>
  <id>testservice</id>
  <name>Test Service</name>
  <description>This is a test service.</description>
  <executable>"%BASE%\java\bin\java"</executable>
  <arguments>-jar "%BASE%\testservice-1.0.0-SNAPSHOT-runner.jar"</arguments>
  <logmode>rotate</logmode>
  <stopparentprocessfirst>true</stopparentprocessfirst>
</service>

Check the executable path and arguments. %BASE% is an environment variable that points to the directory where the WinSW executable is located.
If you want to start the application with a Java that is on the %PATH%, just use <executable>java</executable>.

Relevant here is <stopparentprocessfirst>. This tells WinSW to shut down the parent process first. In our case, this is useful
because the main process opens a console (java), which can respond to Ctrl+C and will gracefully shutdown the child process (the Java application).

Check out this wiki page to learn more about all the supported options:
https://github.com/winsw/winsw/blob/master/doc/xmlConfigFile.md

Directory structure ¶

The directory structure of my install folder:

testservice.exe
testservice.xml
testservice-1.0.0-SNAPSHOT-runner.jar
java
  bin
    java.exe
    ...
  conf
  legal
  lib
  ...

Installation ¶

With everything in place, you can install the Windows service with this command:

testservice.exe install

The WinSW command supports the following options:

  • install: Install the service
  • uninstall: Uninstall the service
  • start: Start the installed service
  • stop: Stop the service
  • restart: Restart the service
  • status: Show the current service status (NonExistent, Started, Stopped)

The service by default is installed with start mode Automatic. That means Windows starts
the service when it boots up. You can change that with the <startmode> configuration in the XML file.

  <startmode>Manual</startmode>

To test the installation, open http://localhost:8080 in a browser. You should see the default start page of Quarkus.
To test if the graceful shutdown works, stop the service:

testservice stop

Open the file testservice.out.log.

2020-05-06 05:30:52,501 INFO  [io.quarkus] (main) Profile prod activated. 
2020-05-06 05:30:52,501 INFO  [io.quarkus] (main) Installed features: [cdi, resteasy]
2020-05-06 05:30:54,801 INFO  [io.quarkus] (main) testservice stopped in 0.032s

We see that the application shutdown gracefully because of the testservice stopped log entry.

Note that WinSW creates by default three log files:

  • <service>.out.log: Console output from the application (System.out.println)
  • <service>.err.log: Error output from the application (System.err.println)
  • <service>.wrapper.log: Log output from WinSW itself

That concludes this tutorial about installing any Java applications as a Windows Service.
Optionally, you could try and create a native image of your application with
GraalVM.
The service installation does not change much. You don’t need the JRE
anymore and have to change <executable> accordingly.

Introduction

On a Windows operating system, the usual method of running a Java application is via its command line terminal or the Powershell. However, there are some restrictions when running a java application through these terminals. The user with the required rights must be logged on at all times. Also, the terminal must be open and running.

Under many circumstances, this is not desirable. So, often times, some other method of running the application is desirable.

To address these issues, Windows has to capability to run applications as services in the background. Services start up with the system and don’t need a user to be logged in. Basically it is similar to a UNIX daemon. Java applications cannot directly be run as a windows service. But thanks to Java service wrappers, it can be easily done. Additionally, additional features like error recovery, log file rollover, restart on failure can also be provided to ensure that the Service runs continuously.

In this blog post, we will take a look on how to run a Java application as a window service.

Пройдите тест, узнайте какой профессии подходите

Работать самостоятельно и не зависеть от других

Работать в команде и рассчитывать на помощь коллег

Организовывать и контролировать процесс работы

Быстрый ответ

Чтобы преобразовать ваше Java-приложение в службу Windows, вы можете использовать инструмент Apache Commons Daemon’s prunsrv. Для этого выполните следующую команду:

Замените myAppPath на путь к вашему приложению, ВашОсновнойКласс на имя вашего основного класса и добавьте методы startService и stopService для управления жизненным циклом службы. С помощью prunsrv.exe вы сможете управлять службой: запускать, останавливать и удалить её.

Кинга Идем в IT: пошаговый план для смены профессии

Доступные инструменты

В вашем распоряжении множество инструментов для создания службы. Для систем на базе Windows рекомендуется использовать Procrun из пакета Apache Commons Daemon, а для Unix-систем подходит Jsvc.

Руководство по созданию службы

Если не хотите вносить изменения в существующие методы приложения, создайте отдельный загрузочный класс, который будет взаимодействовать с Procrun, принимая команды start и stop.

Настройка и управление

WinRun4J предоставляет возможности для детализированной настройки: вы сможете задавать собственные иконки и отслеживать состояние вашей службы через системный трей.

Визуализация

Ваше Java-приложение превращается в автономную службу Windows с помощью мощного инструмента Apache Procrun.

Подготовка вашего Java-приложения к работе в качестве службы

Чтобы преобразовать ваше приложение в службу, выполните следующие действия:

  • Упакуйте приложение в .jar файл.
  • Настройте Procrun таким образом, чтобы он запускал ваш .jar файл при необходимости.
  • Ищете вдохновение? Обратите внимание на успешные проекты, такие как Tomcat, или изучите Java Service Wrapper и WinRun4J.

Выбор наиболее надежного решения для долгосрочной работы

Выбирайте решение, которое обеспечит стабильность и надежность вашей службы в долгосрочной перспективе:

  • YAJSW на GitHub характеризуется стабильной работой и регулярными обновлениями.
  • WinRun4J предлагает на выбор удобные инструменты мониторинга.

Полезные материалы

  1. Daemon – Daemon: Java based daemons or services — официальная документация Apache по созданию нативных служб на основе Java-приложений.
  2. GitHub – yajsw/yajsw: Mirror of YAJSW repository — GitHub-репозиторий с надежным решением для создания обертки Java-сервиса.
  3. WinRun4J — гибко настраиваемый Java Service Wrapper.
  4. Download Java Service Wrapper — Скачайте Tanuki Wrapper для повышения защищенности и управляемости вашего программного обеспечения.
  5. WrapperSimpleApp Integration (Windows) — пошаговое руководство интеграции Tanuki Java Service Wrapper.
  6. How to create a windows service from java app – Stack Overflow — обсуждение на форуме Stack Overflow, где знаниями делится профессиональное сообщество.
  7. Daemon – Daemon: Procrun — подробная документация для освоения Procrun.

Join the DZone community and get the full member experience.

Join For Free

It sounds like something you’d never need, but sometimes, when you distribute end-user software, you may need to install a java program as a Windows service. I had to do it because I developed a tool for civil servants to automatically convert and push their Excel files to the opendata portal of my country. The tool has to run periodically, so it’s a prime candidate for a service (which would make the upload possible even if the civil servant forgets about this task altogether, and besides, repetitive manual upload is a waste of time).

Even though there are numerous posts and StackOverflow answers on the topic, it still took me a lot of time because of minor caveats and one important prerequisite that few people seemed to have – having a bundled JRE, so that nobody has to download and install a JRE (would complicate the installation process unnecessarily, and the target audience is not necessarily tech-savvy).

So, with maven project with jar packaging, I first thought of packaging an .exe (with launch4j) and then registering it as a service. The problem with that is that the java program uses a scheduled executor, so it never exits, which makes starting it as a process impossible.

So I had to “daemonize” it, using commons-daemon procrun. Before doing that, I had to assemble every component needed into a single target folder – the fat jar (including all dependencies), the JRE, the commons-daemon binaries, and the config file.

You can see the full maven file here. The relevant bits are (where ${installer.dir} is ${project.basedir}/target/installer}):

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.3.2</version>
    <configuration>
        <source>1.8</source>
        <target>1.8</target>
    </configuration>
</plugin>
<plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <executions>
        <execution>
            <id>assembly</id>
            <phase>package</phase>
            <goals>
                <goal>single</goal>
            </goals>
            <configuration>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
                <finalName>opendata-ckan-pusher</finalName>
                <appendAssemblyId>false</appendAssemblyId>
            </configuration>
        </execution>
    </executions>
</plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-antrun-plugin</artifactId>
    <version>1.7</version>
    <executions>
        <execution>
            <id>default-cli</id>
            <phase>package</phase>
            <goals>
                <goal>run</goal>
            </goals>
            <configuration>
                <target>
                    <copy todir="${installer.dir}/jre1.8.0_91">
                        <fileset dir="${project.basedir}/jre1.8.0_91" />
                    </copy>
                    <copy todir="${installer.dir}/commons-daemon">
                        <fileset dir="${project.basedir}/commons-daemon" />
                    </copy>
                    <copy file="${project.build.directory}/opendata-ckan-pusher.jar" todir="${installer.dir}" />
                    <copy file="${project.basedir}/install.bat" todir="${installer.dir}" />
                    <copy file="${project.basedir}/uninstall.bat" todir="${installer.dir}" />
                    <copy file="${project.basedir}/config/pusher.yml" todir="${installer.dir}" />
                    <copy file="${project.basedir}/LICENSE" todir="${installer.dir}" />
                </target>
            </configuration>
        </execution>
    </executions>
</plugin>

You will notice the installer.bat and uninstaller.bat which are the files that use commons-daemon to manage the service. The installer creates the service. Commons-daemon has three modes: .exe (which allows you to wrap an arbitrary executable), Java (which is like .exe, but for java applications) and JVM (which runs the java application in the same process; I don’t know how exactly though).

I could use all three options (including the launch4j created .exe), but the JVM allows you to have a designated method to control your running application. The StartClass/StartMethod/StopClass/StopMethod parameters are for that. Here’s the whole installer.bat:

commons-daemon\prunsrv //IS//OpenDataPusher --DisplayName="OpenData Pusher" --Description="OpenData Pusher"^
     --Install="%cd%\commons-daemon\prunsrv.exe" --Jvm="%cd%\jre1.8.0_91\bin\client\jvm.dll" --StartMode=jvm --StopMode=jvm^
     --Startup=auto --StartClass=bg.government.opendatapusher.Pusher --StopClass=bg.government.opendatapusher.Pusher^
     --StartParams=start --StopParams=stop --StartMethod=windowsService --StopMethod=windowsService^
     --Classpath="%cd%\opendata-ckan-pusher.jar" --LogLevel=DEBUG^ --LogPath="%cd%\logs" --LogPrefix=procrun.log^
     --StdOutput="%cd%\logs\stdout.log" --StdError="%cd%\logs\stderr.log"


commons-daemon\prunsrv //ES//OpenDataPusher

A few clarifications:

  • The JVM parameter points to the JVM .dll (to be honest, I’m not sure if this will work if there is no other java installation on the machine; it should)
  • The StartClass/StartMethod/StopClass/StopMethod point to a designated method for controlling the running application. In this case, starting would just call the main method, and stopping would shut down the scheduled executor, so that the application can exit
  • The classpath parameter points to the fat jar
  • Using %cd% is risky for determining the path to the current directory, but since the end-users will always be starting it from the directory where it resides, it’s safe in this case.

The windowsService looks like that:

public static void windowsService(String args[]) throws Exception {
     String cmd = "start";
     if (args.length > 0) {
        cmd = args[0];
    }

    if ("start".equals(cmd)) {
        Pusher.main(new String[]{});
    } else {
        executor.shutdownNow();
        System.exit(0);
    }
}

One important note here is the 32-bit/64-bit problem you may have. That’s why it’s safer to bundle a 32-bit JRE and use the 32-bit (default) prunsrv.exe.

I then had an “installer” folder with JRE and commons-daemon folders and two bat files and one fat jar. I could then package that as a self-extractable archive and distribute it (with a manual, of course). I looked into IzPack as well, but couldn’t find how to bundle a JRE (maybe you can).

That’s a pretty niche scenario – usually we develop for deploying to a Linux server, but providing local tools for a big organization using Java may be needed every now and then. In my case the long-running part was a scheduled executor, but it can also run a jetty service that serves a web interface. Why would it do that, instead of providing a URL – in cases where access to the local machine matters. It can even be a distributed search engine (like that) or another p2p software that you want to write in Java.

Java (programming language)
application
Web Service

Published at DZone with permission of Bozhidar Bozhanov, DZone MVB.

See the original article here.

Opinions expressed by DZone contributors are their own.

Related

Понравилась статья? Поделить с друзьями:
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
  • Bolid драйвер для usb rs485 для windows 10
  • Как установить wsus на windows server 2019
  • Windows 8 build 8102 x86
  • Best antivirus for mac and windows
  • Bios не видит загрузчик windows