Convert a java application into a Linux service 
Tags: linux, java, sysadmin, tutorial
Published: 2021-11-26 23:17:16

First of all, a **Linux Service** is an application that runs in the background and performs an essential task. One of the advantages to use a service is that you do not need to start it manually, you can configure it to start with the system using this command:
```
sudo systemctl enable <service_name>
```

Some of the most commonly used services are:
* httpd
* mysql
* chronyd
* sshd 

You can list all the services inside your Server using
```
systemctl list-units --type=service
```

Also you can see the status of an specific service using:
```
systemctl status <service_name>
```
Let see an example:
```
[ernesto.lopez@test-vm ~]$ systemctl status chronyd.service
● chronyd.service - NTP client/server
   Loaded: loaded (/usr/lib/systemd/system/chronyd.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2021-11-02 12:31:04 MST; 3 weeks 3 days ago
     Docs: man:chronyd(8)
           man:chrony.conf(5)
 Main PID: 1212 (chronyd)
    Tasks: 1 (limit: 98556)
   Memory: 1.1M
   CGroup: /system.slice/chronyd.service
           └─1256 /usr/sbin/chronyd
```
To explain this output:
* **chronyd.service - NTP client/server**: is the name of the service and a small description of it.
* **Loaded: loaded (/usr/lib/systemd/system/chronyd.service;** : means that the services located in the path that appears was loaded in memory
* **enabled; vendor preset: enabled)** : this part indicate that the service is enable, so it will start at boot, this is achieved using the command `sudo systemctl enable`
* **Active: active (running)** : this means that the service is up and running in the system, this line usually appears on green if you are using a normal user. This line also notifies the user when this service was started.
* **Main PID: 1212 (chronyd)** : this line shows the process ID for this service. you can then use `ps 1212` to get the command associated with the service.

These lines represent an important aspect to evaluate a service, cGroup deserve a single post entry.

***********************************************************

**NOTE** Before converting anything to a service, make sure you have installed java on your server. A quick using dnf and java 8 example:
```
sudo dnf -y update
sudo dnf -y install java-1.8.0-openjdk-devel
java –version
 
 #Find your java home path
sudo alternatives --config java 
```
Add this line into your profile file (**/etc/profile**) to easier the following steps:
 
>export JAVA_HOME=$(dirname $(dirname $(readlink $(readlink >$(which javac)))))
>export PATH=$PATH:$JAVA_HOME/bin
>export >CLASSPATH=.:$JAVE_HOME/jre/lib:$JAVA_HOME/lib:$JAVA_HOME/lib/tools.jar

Save the file and set the system to use this profile

```
sudo source /etc/profile
```
You can verify that the configurations were correct, by running: 
```
echo $JAVA_HOME
echo $PATH
echo $CLASSPATH
```
***********************************************************

Back to the starting our java app, suppose our app is in a .jar file called **my-own-app.jar**

> JAR stands for Java ARCHIVE, it is a file format used to aggregate many java files into one.

More on the official documentation from [Oracle](https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jarGuide.html)

And for example we have our application stored inside `/opt/my-own-app/` directory

First thing that we are going to do is to create a script that start the app, imagine we are going to convert our java app in a bash script (Just an imagination exercise!)

```
cd /opt/my-own-app
touch my-own-app.sh
vi !$
```

Then, we need to tell the script to start the app in the .jar file 

```
#!/bin/bash 
# Script to start MyOwnApp
echo "--------------------WAIT-------------------" 
# Start the app 
# minimum heap 512MB, maximum heap 1GB 
cd /opt/my-own-app 
java -Xms512M -Xmx1G -jar my-own-app.jar &
```
Here we are creating a script that move tho the directory where the .jar file is located and then execute the java command which is used to launch a java application. The elements to consider:
* **-Xms512M** specifies the initial sizeo of the memory allocation pool, in this case we append M to indicates it is megabyte. This value must be determined based on app consumption.
* **-Xmx1G** is the maximum size of the memory allocation pool, this case indicates 1G but can vary depending on your app.
* **-jar** define the location of the jar file, because in the previous step in the script we move to the `/opt/my-own-app` dir, we use just the name of the file in this case.

Save the file and change the permissions to make it an executable:
```
sudo chmod u+rwx my-own-app.sh
ls -l | grep my-own-app.sh 
```

Next step is to create a service unit:
```
vi /etc/systemd/system/my-own-app.service 
```

**Note** A service unit describes how to manage a service or application on the server.

Insert the following information on the file:
```
[Unit]
Description=my own app starting
After=network.target

[Service] 
Type=forking
ExecStart=/opt/my-own-app/my-own-app.sh
TimeoutStartSec=0

[Install] 
WantedBy=default.target

```

The important aspects of this:
* **WantedBy=default.target** defines how a unit should be enabled, this represents the default and will create a file `.want` append inside `/etc/systemd/directory`
* **Type=forking** tells the systemd that the process is still running even though the parent process exited.
* **ExecStart=/opt/my-own-app/my-own-app.sh** is the file to be executed.
* **After=network.target** the service must be started after network services.

The following step is to reload the systemd daemon
```
sudo systemctl daemon-reload
```

And finally enable and start the service
```
sudo systemctl start my-own-app.service
sudo systemctl enable my-own-app.service
```

You can verify if the service started ok or if there was any trouble using
```
sudo systemctl status my-own-app.service
```