I have a java program acting as a Network server. Thanks the the utility update-rc.d I have installed a service on a Debian / Unix server in order to have it running all the time without being connected during a SSH session.
Because my program is in java bytecode, and not a native unix executable, I have used the following tutorial to make it work as a daemon: java as a daemon service
The problem is that I don't see the output of the program any more. I need to see the output of the program, as it shows a stack trace when an exception happens. How to redirect standard and error output streams to a log file ?
Alternative question: How to run the java program and have it continusly running even when I log out from SSH ?
You can wrap the app launch command into a shell script and redirect output there:
/usr/bin/java -jar app.jar >> /var/log/app/app.log 2>&1
But I'd recommend to use some logging framework to gain more control over log files. Something like slf4j with logback or any other backend.
Alternative question: How to run the java program and have it continusly running even when I log out from SSH ?
You can do this with screen:
screen java -jar app.jar ...
Then after SSH login run
screen -r
to resume screen session.
Related
I have a script.sh that set some environment variable and start a java server.
#!/bin/bash
export JAVA_HOME="/opt/java"
export ....
nohup $JAVA_HOME/bin/java "$MEMORY_JAVA_OPS" -classpath "$MY_CLASSPATH" $MAIN_CLASS &
I would like to transform this script (now is launched by /etc/rc.d/rc.local) in a service.
I tried many examples found online and over StackOverflow.
I created myservice.service file using many templates found online... No one work!
one example is:
[Unit]
Description=MyService Java Process Restart Upstart Script
After=auditd.service systemd-user-sessions.service time-sync.target
[Service]
User=root
TimeoutStartSec=0
Type=simple
KillMode=process
#export JAVA_HOME=/opt/java/jdk-9
#export PATH=$PATH:$JAVA_HOME/bin
WorkingDirectory=/tmp/myworkdir
ExecStart=/path/to/myscript.sh
[Install]
WantedBy=multi-user.target
With some configurations, the service starts but the status command says that it is dead (while it is actually running). With others it does not start. With none it stops with the command stop ....
I tried Type=Simple, forking, oneshot... always some problem.
I would simply that after boot or when user launch systemctl start myservice, service start, and if after some time crash will be started again. And if I will run systemclt stop myservice it stops and not need to kill the process.
Firstly it need to be said, that concept "service" greatly differs in Linux/Unix and Windows environment. From your question seems to me you are looking for Unix solution.
In unix you typically register some statup and stop script/command. The startup script just runs your java application via java -jar app.jar. This application does business logic & also opens listening on some SHUTDOWN port.
The stop script/command just invokes another (or the same with different cmd parameters) java application which does nothing else just sending STOP command to original application's SHUTDOWN port.
You can look in more detail for example on tomcat startup/stop scripts - they are doing exactly this.
For windows is better to use some wrappers like WinRun4J or whatever else. Of course you can have one multiplatform maven archetype for "universal multiplatform" service like we do.
EDITED:
If you are still unsure how to configure it on Linux, read https://linuxconfig.org/how-to-create-systemd-service-unit-in-linux
ExecStart will be the startup java -jar app.jar and ExecStop will be the stopping command java -jar app-stopper.jar
Spring has this documentation for running an executable spring boot jar.
However, I ran this jar from terminal using the nohup linux command, and worked fine.
The question is: Using nohup or using init.d service, will have the same result for the application? Or using the init.d is the correct way always?
They do different things. nohup runs a command, and ignores the HANGUP (HUP) signal. init.d is for running a command automatically at server start-up (and shutting commands down orderly on shutdown). If you want your spring boot application to run automatically after the system restarts, put it in init.d - if you want to manually start it after every reboot you can use nohup.
nohup runs the command in a way that will be immune to hangups, which could cause problems. A lot of programs are designed to re-read their configuration files, restart, or do other things when they receive HUP signals (most services/daemons restart or re-read configs). Unless you specifically want to ignore HUP signals, using nohup isn't the best solution.
You can use & after the command in order to run it in the background, and if you want to avoid output to the terminal, you can send the output to /dev/null:
mycommand > /dev/null 2>&1 &
The 2>&1 will send stderr to stdout, so it goes to /dev/null.
I've been stuck two weeks trying to figure out how to run this at startup.
I use the following chain of commands on the terminal:
1. source ~/.bashrc
2. source ~/.tinyos.sh
3. java net.tinyos.tools.Listen -comm serial#/dev/ttyUSB0:telosb | python demo.py`
The third command uses java to listen to the serial port and pipes it to a python script which cleans, converts and uploads to mysql localhost.
This works fine on ssh terminal. But ive tried using nohup+update-rc.d, upstart, systemd, crontab to make it run on startup and it just wont work! When I reboot and check logs / database, its as if the command never happened. I need this to run like a daemon and continue running until shutdown.
Thanks a lot.
How are you trying to execute the program ? Are there are permission issues accessing / executing the script ?
Which version of debian are you running - look at upstart scripts if you are running Jesse+
I'd put those three lines in a bash script and use upstart scripts to trigger them on start. Another option is to use supervisord to make sure that your scripts run and restart if for any reason the program crashes.
This question already has answers here:
How to Daemonize a Java Program?
(11 answers)
Closed 7 years ago.
I have built a little daemon in Java and I would like to run it as a service under Unix (e.g. Debian 5). I have read that there is a possibility of using a Java wrapper, but isn't there any other option which is easier to implement? Can't I just use a Unix command such as xxx java -jar program.jar?
Well, if you want to run your java program even when you exit out of your shell, the following is the most simple way:
$nohup java -jar program.jar &
You need to create an appropriate script in /etc/init.d and link it to /etc/rcX.d directories. The script should support at least start, stop, and status parameters. During start it should run java command with appropriate arguments, probably via nohup java <arguments> &. Then you should save PID of your newly-started process to file /var/run/yourservice.pid. stop command should read this PID file and kill this service.
The details vary from distribution to distribution, most distributions provide some macros to make whole job easier. It's best to look at examples of other services in /etc/init.d for your distribution.
Additionally:
If your service isn't accessed from other computers from the network, but it opens some port, make it unavailable with firewall.
If your service processes some 'delicate' data, it's good to add another user and invoke an appropriate sudo command in your /etc/init.d file.
You can start it as:
java -jar program.jar
Unix daemons are normally started by init or started by a script in /etc/init.d or /etc/rc.d, and started at specific runlevels - normally by soft links in /etc/rcX.d. (where X is the intended "runlevel" which is normally 3.
I think debian are moving to using "upstart", a init-replacement. It uses config files in /etc/init to define jobs, and they are quite easy to write. Check that out.
Daemons traditionally closes stdin, sdtout and stderr, and does a "double fork" when starting, in order to detach from the session and also to signal that they are ready to handle whatever they should handle. This is not really necessary, as long as the daemon is not started from the terminal.
If you want a simple shell wrapper to start you program; you just need to write a small shell script:
#!/bin/sh
/full/path/to/java -jar /full/path/to/program.jar
... and make it executable (chmod 755 )
This article contains a few useful tricks for running a Java application as a daemon:
http://barelyenough.org/blog/2005/03/java-daemon/
Alternatively, you can have a look at the Apache Commons Daemon project, although this requires native code (Unix and Win32 supported):
http://commons.apache.org/daemon/
You can use a cron job to schedule your program. You can also check out this article for details on how to run scripts on startup. You can write a script that runs your java program and run it on startup as mentioned in the article.
How to catch Java application output (System.out.println()) when connected to remote host (OS Solaris) via Putty if remote session is lost and connected again? Java application on remote host was started like this:
java -jar /SomeApplication.jar &
Now the output is visible. But if I exit remote session and connect again - no more output is visible, though the same java application is still running - I can see it by issuing this command:
ps -ef | grep java
Output is:
root 5221 1 0 20:04:15 ? 1:20 java -jar
SomeApplication.jar
The application ID is 5221 and it is running, but it's output vanishes somewhere..
A quick and neat suggestion is running the application in a screen session (check the Solaris package).
First, you launch screen:
$ screen
Then you launch the application inside screen, like usual:
$ java -jar /SomeApplication.jar
And you are set. You don't need the trailing &: you can detach (see below) and log out; the screen session will be kept running. On next login, just issue:
$ screen -x
and the session, with its output, will be reattached.
A quick reference:
Use CTRL+a d (first CTRL+a together, then d) to detach from the session, so that you leave the screen session (with the java application running inside), go back to the Solaris shell and do other things -- including logging out graciously.
Use CTRL+a ] to enter "copy mode", so that you can scroll up and down and q to leave copy mode.
There are many other useful features, just read a quick intro :)
Log files play better in these scenarios.And sysouts are expensive operations too.
Or when you start the java program, redirect error/outputs to a temp file. So you can view it later.
java -jar /SomeApplication.jar > wherever_you_want_output.log 2>&1 &
the > redirects system.out.println to the file, the 2>&1 sends the system.err.println to the same file (you could also put 2> error_file.log to get a separate System.err.println() output.
Long term though you should use a logging framework through like log4j or the java logging framework.
If you want to watch the output then as it grows, you can do a tail -f whatever_you_want_output.log