Linux java jar as service

Run a Java Application as a Service on Linux

announcement - icon

The Kubernetes ecosystem is huge and quite complex, so it’s easy to forget about costs when trying out all of the exciting tools.

To avoid overspending on your Kubernetes cluster, definitely have a look at the free K8s cost monitoring tool from the automation platform CAST AI. You can view your costs in real time, allocate them, calculate burn rates for projects, spot anomalies or spikes, and get insightful reports you can share with your team.

Connect your cluster and start monitoring your K8s costs right away:

1. Introduction

Any Java application from the system point-of-view is just an instance of the Java Virtual Machine. In this short tutorial, we’ll see how we can make our applications run as system services.

We’ll use the facilities of the systemd software package. systemd is the initialization and service management system in most modern Linux distributions.

Throughout the tutorial, we’ll consider two implementations: one for a simple case and one for a more advanced case.

2. Simple Service

In the systemd world, to create a system service, we need to prepare a unit file and register it the proper way. We’ll discuss the file location shortly, but first, let’s start with the content:

[Unit] Description=My Java driven simple service After=syslog.target network.target [Service] SuccessExitStatus=143 User=appuser Group=appgroup Type=simple Environment="JAVA_HOME=/path/to/jvmdir" WorkingDirectory=/path/to/app/workdir ExecStart=$/bin/java -jar javaapp.jar ExecStop=/bin/kill -15 $MAINPID [Install] WantedBy=multi-user.target

We set the Type of service to simple because the system starts the JVM process directly, without spawning a child process.

ExecStop specifies the service termination command, and systemd is smart enough to figure out the PID of the started process. It automatically creates a MAINPID environment variable.

Then, we instruct systemd to send a 15 (SIGTERM) system signal to terminate the process gracefully.

The JVM designers made Java return a non-zero exit code in case it is terminated by a system signal. As a non-zero base, they took 128, and the resulting exit code is a sum of 128 and the signal numeric value.

By setting SuccessExitStatus to 143, we tell systemd to handle that value (128+15) as a normal exit.

3. Forking Service

The simple service unit file above might be quite sufficient for trivial applications. However, more practical cases will probably include additional settings.

These can be JVM parameters as well as any other application-specific parameters, for example, config or data file locations. That may result in writing a wrapper shell script where we can set up all the required parameters before starting the JVM.

Let’s imagine we already have a wrapper script and now just want to turn it into a system service:

#!/bin/bash JAVA_HOME=/path/to/jvmdir WORKDIR=/path/to/app/workdir JAVA_OPTIONS=" -Xms256m -Xmx512m -server " APP_OPTIONS=" -c /path/to/app.config -d /path/to/datadir " cd $WORKDIR "$/bin/java" $JAVA_OPTIONS -jar javaapp.jar $APP_OPTIONS

Since we use a shell script to start the service, the JVM will be started by the shell (bash) process. This operation is known as fork, and it’s why we set the service Type to forking.

Moving variable definitions into the script’s body also makes the unit file more concise:

[Unit] Description=My Java forking service After=syslog.target network.target [Service] SuccessExitStatus=143 User=appuser Group=appgroup Type=forking ExecStart=/path/to/wrapper ExecStop=/bin/kill -15 $MAINPID [Install] WantedBy=multi-user.target

4. Registering and Running the Service

No matter what service type we choose, to complete the mission, we must know how to set up and run the system service itself.

Читайте также:  Linux bash script exit

First, we need to name the unit file after the service name we want to have. In our examples, that could be javasimple.service or javaforking.service.

Then, we put the unit file under one of the locations where systemd can find it. For an arbitrary service, /etc/systemd/system is a good choice.

The full path to our system units, in that case, will be:

Another possible path to place system units is /usr/lib/systemd/system. This is typically the location used by the system installation packages.

However, we should consider it more appropriate when we develop our own .rpm or .deb installation packages containing system services.

In either case, we’ll control the service using the systemctl utility and pass either the start, stop, or status command.

Before that, however, we should notify systemd that it has to rebuild its internal service database. Doing this will make it aware of the new system unit we introduced. We can do this by passing the daemon-reload command to systemctl.

Now, we’re ready to run all the commands we mentioned:

sudo systemctl daemon-reload sudo systemctl start javasimple.service sudo systemctl status javasimple.service ● javasimple.service - My Java driven simple service Loaded: loaded (/etc/systemd/system/javasimple.service; disabled; vendor preset: disabled) Active: active (running) since Sun 2021-01-17 20:10:19 CET; 8s ago Main PID: 8124 (java) CGroup: /system.slice/javasimple.service └─8124 /path/to/jvmdir/bin/java -jar javaapp.jar

We’ll need to run the daemon-reload command each time we modify the unit file.

Next, we notice the system reports our service running but disabled. Disabled services will not start automatically when the system boots.

Of course, we can configure it to start up automatically along with the system. This is where we use another systemctl command — enable:

sudo systemctl enable javasimple.service Created symlink from /etc/systemd/system/multi-user.target.wants/javasimple.service to /etc/systemd/system/javasimple.service

Now, we can see that it’s enabled:

sudo systemctl status javasimple.service ● javasimple.service - My Java driven simple service Loaded: loaded (/etc/systemd/system/javasimple.service; enabled; vendor preset: disabled) Active: active (running) since Sun 2021-01-17 20:10:19 CET; 14min ago Main PID: 8124 (java) . 

5. Conclusion

In this article, we looked at two possible ways of turning Java applications into system service by means of systemd.

Java is still one of the most popular programming languages. A lot of Java applications are designed to run non-interactively for a variety of tasks, such as processing data, providing an API, monitoring events, and so on. Thus, they all are good candidates to become system services.

Читайте также:  Etc rc local in linux

Источник

Running a Java Application as a Service

To control our application, we’re going to run it as a systemd service. Wikipedia defines systemd as:

a software suite that provides an array of system components for Linux operating systems. Its main aim is to unify service configuration and behavior across Linux distributions; systemd’s primary component is a «system and service manager» — an init system used to bootstrap user space and manage user processes.

To create a service, we need to have the relevant access to the server, so we need to ensure we have sudo access.

The first stage in defining the application as a service, is to create a file within the /etc/systemd/system directory with a name of myapp.service

/etc/systemd/system/myapp.service 

Within this file, we need to add 3 sections. [Unit] defines the description of the service, [Service] defines how the service is executed and [Install] tells the operating system when to run the application. For example

[Unit] Description=My Application As A Service [Service] User=myapp_user Group=myapp_group Type=simple ExecStart= java -jar /home/ubuntu/myapp/myapp.jar -Xmx512m –Xms512m -XX:MaxNewSize=384m -XX:MaxPermSize=128m SuccessExitStatus=143 [Install] WantedBy=multi-user.target 

Let’s take a look at each of these sections in turn.

[Unit]

This section simply contains one entry which is the description of the service. Note, the name of the service is defined by the name of the file within the /etc/systemd/system directory.

[Service]

This section defines details that the operating system requires to be able to start the service. Firstly, the User and Group specify the security details for the application to run. The application is run as this specified user and group and has their permissions.

Type can be set to simple for most cases. This defines that the application will run immediately without forking any other processes. For a definition of the other options available here, check out the man pages for systemd.

Next, ExecStart specifies the command that is used to run the application. Here, we specify the entire command line (including java and any parameters) to run the application. This can be very useful as we can specify which version of Java to use here, so an application can be configured to run with any required JVM, and not only with the system’s default JVM. Any JVM properties or application variables can be configured here.

Finally, as we’re running a Java application, we need to tell it how to play properly with systemd. When a Java application is killed via a SIGTERM event, the JVM will close down cleanly but will return an exit code of 143. Adding this as a SuccessExitStatus tells systemd that the application has closed cleanly in this situation.

[Install]

The last section basically tells systemd that if the application is configured to start at server boot time, then do so as part of the normal boot process. This tells systemd that the application can start at boot time, but not that it necessarily will. Read on for how we do that.

Controlling the Service

Once the .service file has been created, we need to tell systemd that we have a new service. This is achieved by executing:

sudo systemctl daemon-reload 

Once executed, we can start and stop the service via:

sudo systemctl start myapp sudo systemctl stop myapp 

We can get the status of the application by executing:

sudo systemctl status myapp 

Finally, if we want to tell the systemd to start the application at boot time, we can execute the following command:

sudo systemctl enable myapp 

Restarting upon Failure

Now that we’ve seen how to create and manage a service, the only thing remaining is to tell systemd to restart the service in case of a failure.

Читайте также:  Create local domain linux

That can be achieved by adding the following entries into the [Service] section of the file.

Restart=on-failure RestartSec=10s 

This configuration tells systemd to restart the service 10s after a failure (you can obviously customise this to your required time interval).

There are other options available here, for example, when the service is to restart and how many attempts to be made. For more information, check out the man pages for systemd.

Conclusion

In this post we’ve seen how to run a Java application as a service using systemd, and how to control it. We’ve seen how to start the service at boot time and how to restart the service upon failure.

Источник

Run Your Java App as a Service on Ubuntu

Join the DZone community and get the full member experience.

Say you have a JAR file and you need to run it as a service. Additionally, you want it to start automatically if/when system restarts.

Ubuntu has a built-in mechanism to create custom services, enabling them to get started at system boot time and start/stop them as a service. In this post, I am going to share a simple and elegant way to create a service wrapper for your JAR file so you can run it as a service. Here we go.

Step 1: Create a Service

sudo vim /etc/systemd/system/my-webapp.service

Copy/paste the following into the file /etc/systemd/system/my-webapp.service :

[Unit] Description=My Webapp Java REST Service [Service] User=ubuntu # The configuration file application.properties should be here: #change this to your workspace WorkingDirectory=/home/ubuntu/workspace #path to executable. #executable is a bash script which calls jar file ExecStart=/home/ubuntu/workspace/my-webapp SuccessExitStatus=143 TimeoutStopSec=10 Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target

Step 2: Create a Bash Script to Call Your Service

Here’s the bash script that calls your JAR file: my-webapp

#!/bin/sh sudo /usr/bin/java -jar my-webapp-1.0-SNAPSHOT.jar server config.yml

Don’t forget to give your script execute permission: sudo chmod u+x my-webapp

Step 3: Start the Service

sudo systemctl daemon-reload sudo systemctl enable my-webapp.service sudo systemctl start my-webapp sudo systemctl status my-webapp

Step 4: Set Up Logging

First, run: sudo journalctl —unit=my-webapp . See real-time logs by using the -f option.

If you want to trim them, use -n to view the specified number of lines of the log:

sudo journalctl -f -n 1000 -u my-webapp

Tail the live log using the -f option:

sudo journalctl -f -u my-webapp

Stop the service by using:

sudo systemctl stop my-webapp

That’s it! Enjoy and show your support if you like it. Thanks!

Published at DZone with permission of Muhammad Sarwar . See the original article here.

Opinions expressed by DZone contributors are their own.

Источник

Оцените статью
Adblock
detector