1. Introduction
Sometimes, we want to run the Java program in the background and keep it running even after the terminal is closed.
In this tutorial, we’ll explore various ways to achieve this. We’ll look at how to run the Java process as an independent session that continues even after closing the terminal.
2. Running Java as a Background Process
One of the simplest ways to run the Java program in the background is by using the & operator inside a shell script:
#!/bin/sh
java -jar /web/server.jar &
echo $! > startupApp.pid
The & ensures that the process runs in the background, allowing us to use the terminal without waiting for it to finish.
The $! > startupApp.pid captures and stores the PID (Process ID) of the last executed background command. This PID uniquely identifies the running process and can be used later for process management tasks like monitoring or stopping it.
However, there is one downside to this approach. Even though we can continue to use the terminal, the process may still get terminated if we close the terminal. This can cause the background program to stop unexpectedly.
Also, it’s harder to control the process properly as it’s not managed as a service. We don’t get to see the logs or start/stop the process easily like we would with a proper service manager like systemd.
3. Keeping the Process Alive With Nohup
If we don’t want the process to end after closing the session, then nohup is the answer. nohup (No Hang Up) lets our process continue running even after we close the session or terminal.
Below is the shell script using nohup:
nohup java -jar /web/server.jar > output.log 2>&1 &
echo $! > startupApp.pid
nohup will keep the process running even if we close the terminal session. The > output.log 2>&1 part helps us redirect both the standard output and error output into a file named output.log, making it easy to check logs later (For debugging purposes). The & in the end, runs the process in the background.
echo $! > startupApp.pid saves the PID in startupApp.pid for future usage.
If we want to kill the process, we can run the below command:
kill $(cat startupApp.pid)
4. Running Java as a systemd Service (for Linux Servers)
For long-running Java processes and better management, we need to manage them as a service using systemd. This is a recommended approach if we are using Linux servers. Let us now take a look at how we can achieve that.
First up, we need to create a .service file using the below command:
sudo nano /etc/systemd/system/myjavaapp.service
Next, add the following content to the file:
[Unit]
Description: Java Background Service
After=network.target
[Service]
ExecStart=/usr/bin/java -jar /web/server.jar
WorkingDirectory=/web
Restart=always
User=root
StandardOutput=append:/var/log/myjavaapp.log
StandardError=append:/var/log/myjavaapp.err
[Install]
WantedBy=multi-user.target
We are trying to define how to run the Java application as a background service. In this case, we’re making sure that the app starts automatically on boot and stays running.
In the [Unit] section, with After=network.target, we specify that it should only start after the network is available. This is important if our Java application is dependent on the Internet or network services.
Next, in the [Service] section, we define how our Java application should run. Let’s break it down.
The ExecStart tells systemd to start the Java application by running the server.jar. The WorkingDirectory defines from which folder the service will execute. In this case, it is set to the /web directory.
The Restart ensures that the systemd will automatically restart the application if the application crashes for any reason.
Next, we set the User property to root, which means the service runs as the root user. However, for better security, it’s generally recommended to run the service as a non-root user.
We’re also keeping track of the logs and errors with the StandOutput and StandardError properties. These would be useful to analyze issues related to the application.
Finally, with the WantedBy=multi-user.target property, we are letting our Java app start automatically when the system reaches the normal working stage for services so that the service would start before the rendering of the GUI. Without this configuration, our service wouldn’t know when it should start automatically. It would just sit there, and we’d have to start it manually after every reboot.
Next, we need to reload the systemd and enable the service. This step is needed whenever we either create or modify a service and let systemd know about the changes.
We need to run the below command to let systemd know about our newly added (or modified) service:
sudo systemctl daemon-reload
Next, we need to create a symbolic link (shortcut) that points to the service file. The system places this shortcut in a special folder, checks it during startup, and starts the service during the multi-user.target stage.
Below is the command to create the symbolic link:
sudo systemctl enable myjavaapp
Now, to start the Java application, we need to either reboot the system or run the below command:
sudo systemctl start myjavaapp
We can use the below command to verify if the service has started:
sudo systemctl status myjavaapp
Finally, to stop the background process, we can run the below command:
sudo systemctl stop myjavaapp
5. Running Java as a Background Process with screen or tmux
Unlike systemd or nohup, screen and tmux allow us to detach (disconnect) from the session without stopping the running process and reattach (reconnect) later to exactly where we left off.
Simply put, using screen or tmux, we can start a Java application, close the laptop or lose connection, and then later come back to see the same terminal as if nothing happened, and the app will keep running in the background.
We can think of it as Windows Hibernate, but limited to terminal sessions.
Let’s use the below command:
screen -S myjavaapp java -jar /web/server.jar
To detach, we need to press Ctrl+A, release both, and then press D. To attach later, we need to run the below command:
screen -r myjavaapp
We can achieve similar results with tmux. Below is the command for the same:
tmux new-session -s myjavaapp 'java -jar /web/server.jar'
To detach, we need to press Ctrl+B, release both, then press D. To attach later, we need to run the below command:
tmux attach-session -t myjavaapp
tmux is more modern, more powerful, and easier to use, while screen is simple and good enough for basic needs. However, most Linux distributions come with screen preinstalled, while we might need to install tmux separately.
6. Conclusion
In this article, we’ve seen how to run a Java application as a background process, explored how to keep it running after closing the terminal session, and even monitored it using logs.
For simple cases, nohup or & can work, but for production environments, using the system is a more reliable method. Tools like screen and tmux give us additional flexibility to continue the process even after rebooting, as if nothing happened. We need to choose the approach that best suits our use case.