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.
Related
I am working on a KTor server. I run the generated jar file using java -jar command. So I expect that only one Java process should run. After running for a while another Java process is being created which is bound to different port.
I checked the details of the process using ps -a [PID] and find this new Java process is "kotlin-compiler-embeddable" program.
I am wondering why this process is being created, what is use of this and is it safe to kill it.
Thanks for any pointer.
kotlin-compiler-embeddable is used in scenarios when you have to package the compiler in a single jar, and no external dependencies. This is the case of Ktor.
I have a .jar file I want to run all the time on a Debian server.
Currently I have figured out how to access the server via ssh on Cygwin and start the .jar. But when I close the Cygwin window on my development machine, it kills the process on the server (I think, as it's not responding any longer).
Currently I start it like this:
java -jar myjar.jar packageName.fileNameOfFileWithMainMethod
I need to make this file run automatically and continually on the server (it is an integral part of the system I am developing).
Unfortunately I know next to nothing about server management, or non-windows operating systems in general (wasn't me who chose or made the server), so I really don't know what to do, nor what to search for (apparently, since my searching gave no usable results).
I have read (and edited because the text was a mess) this question, but although I feel it might be hinting in the right direction, I didn't get much help from it. I also tried my best googlefu, but it got me a lot of only tangentially related results.
I guess I'll have to make some kind of script (possibly containing the code line above), do some stuff to it and put it somewhere specific on the server to accomplish what I want to do.
Would someone be so kind as to explain how this is done?
Shell hooks are good for configuring user environment variables.
Cron is for scheduled jobs, mostly related maintenance, such as creating backups, managing log-files etc ...
Background processes with nohup as advised by Николай Митропольский, or ssh with "screen" application (which let you detach/reattach to a "session"), will be useful in development time.
But can not handle server shutdown cleanups, or respond to restarts.
Init scripts mentioned above is the standard way to start/stop services.
There is an application named init, which is the first application started when a Unix-like system boots.
Init, according to runlevel, starts some scripts, and those scripts manages daemons (services in Windows).
So for services, you write "hooks" for runlevels,
In Debian, /etc/init.d/ where you put your init scripts,
you can read the scripts inside this folder to get the idea,
they are text files (bash scripts).
Those scripts are called with an argument
(a standard keywords, such as "start", "stop" etc..).
/etc/rc?.d/ (where ? is one of runlevels), where the init finds the scripts to run.
But those scripts are just "automatically created" symbolic links to the scripts in /etc/init.d/.
You do not need to touch anything inside /etc/rc?.d/ folder.
*After putting your script into /etc/init.d/,
you only need to call to create symbolic links *:
sudo update-rc.d "your-scripts-name" defaults
As you see there are some prefixes attached to names of scripts;
for example /etc/rc1.d/K10apache2 which is a symbolic link to /etc/init.d/apache2.
So a simple "ordered by name execution" is possible here.
Automatically creating those prefixes (so the execution order),
dependency information is required.
So init scripts includes this information.
Also information required when (at which runlevel) those scripts should be called (with "start" or "stop").
This dependency information is placed as comments in those scripts.
Forexample apache server init script (/etc/init.d/apache2) includes those lines;
# Provides: apache2
# Required-Start: $local_fs $remote_fs $network $syslog $named
# Required-Stop: $local_fs $remote_fs $network $syslog $named
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
Detailed information exists in Debian policy;
https://www.debian.org/doc/debian-policy/ch-opersys.html#s-sysvinit
also this will be usefull;
https://refspecs.linuxbase.org/LSB_2.1.0/LSB-generic/LSB-generic/iniscrptfunc.html
NOTE:
There is a huge transition and debates/fragmentations in Unix world.
Init and init scripts, tradationally used in Unix/Unix-like systems, nowadays becoming obsolete on many systems.
https://en.wikipedia.org/wiki/Init#Replacements_for_init
Debian currently uses systemd, but init scripts still works with systemd (systemd provides the compatibility).
One simple suggestion would be to run the jar file using Linux's CRON.
This article from unix stack exchange should get you going the correct direction for running a jar file using cron.
Alternatively, this article from mkyong.com is also clear and concise.
For example:
Connect using Cygwin
Run crontab -e
Enter 0 * * * * java -jar myjar.jar packageName.fileNameOfFileWithMainMethod to run the jar file every hour at the top of the hour. Or, to start it once on server startup enter #reboot java -jar myjar.jar packageName.fileNameOfFileWithMainMethod
Simplest solution is to detach process by using nohup with &:
nohup java -jar myjar.jar packageName.fileNameOfFileWithMainMethod &
to stop process will be possible with kill <process-id> command
process id could be found by ps -ef | grep packageName.fileNameOfFileWithMainMethod
But if you are developing serious application that is long-running on server you have to deal with initialization system like systemd, upstart or something like that.
I have written a java program with jar file. The java program is to update status of linux server so it need to keep running, but the linux server is in data center, so I need to remote to server to open the program. I use ssh to login linux server. Use command of "java -jar file.jar" to run the program.
However, the java program of the linux server will close if I close the terminal in my computer. Since I cannot keep opening my computer, I wanna know how to open the java programming without holding my computer terminal.
you need to use nohup to keep the program running after you log out.:
server:~name$> nohup java -jar file.jar &
this will keep your program running
Two ways
One
nohup java -jar file.jar &
Another
java -jar file.jar &
In both cases your process will go in background however the process will terminate in the second approach when shell terminates in second case.
If this program is intended to be running on all your machines for monitoring purposes, you should be running it as a service from your server's init system (systemd for most systems these days). You can use the Java Service Wrapper or jsvc or write your own init script.
Another solution apart from the proposed one:
screen -d -m java -jar your.jar
You will then have a detached screen with your java command in it. List with screen -l, reattach with screen -D -RR <screenid_obtained_via_screen_-ls>
I have a somewhat strange issue. I have a java application that installs few services that run as Jars. Previously I used installed Java to run these Jars. There are four services and all will be instantiated from a single batch file with sequential call to each other. Something like this,
start %JAVA_HOME% commandtoruntjarfile
would work and all four services will run in the background and only one java.exe visible in process explorer. So I had another service installed as windows service which would start stop these services by calling the run bat or shutdown bat.
Now the customer requirement changed to using an internalized version of java. I extract java to a location, make our own environment variable name "ABC_HOME" and the required syntax in batch changes to
%ABC_HOME%\javaw commandtorunjarfile
When its run it works. but there is no stopping these. When I go to process explorer I see 4 java.exe running each for the four run commands in the batch file. If I stop the windows service all the four keep working. If I restart the windows service the number of java.exe in process explorer goes to eight and keeps going up until windows has had enough of it.
How do I get around it? I think the solution should be to have the one java process in process explorer but I cant seem to find any solution for that.
[EDIT]
The four sub services are actually XYNT processes. In the normal scenario it would be something like this
[Process1]
CommandLine = java -Xrs -DasService=yes -cp jarfiles
WorkingDir = c: bin scache
PauseStart = 1000
PauseEnd = 1000
UserInterface = No
Restart = Yes
For using java from a specific location the following change was needed
CommandLine = %JAVA_PATH%\bin\java.exe -Xrs -DasService=yes -cp jarfiles
but this wouldn't work as it would not accept the path variable in XYNT.ini file. so I called a batch file here and in that batch file I used the above code. So here is what the change looks like,
CommandLine = batchfile.bat
and in batchfile.bat
%JAVA_PATH%\bin\java.exe -Xrs -DasService=yes -cp jarfiles
Usually, every Java program run on your system has its own virtual machine running, which means: one java.exe/javaw.exe per instance of your program.
I can not tell why it "worked" from your point of view with java.exe like you described first, but the behaviour you described for javaw.exe (having 4 java processes in the process explorer) would be what I'd have expected.
For me the question is not why you're seeing 4 vs. 1 java processes, but how you can start/stop the "services". Killing the Java VM externally doesn't seem a very good solution. I'd consider building some IPC into the Java services that allow you to gracefully terminate the processes.
I need to call Cygwin from Java code ( example : to call make command in Cygwin from Java app which run on linux and windows ).Does anybody have experience with this problem ?
I think you have to differentiate youre code for linux and windows
on linux simply execute the command
on windows lauch your command in cygwin with
C:\cygwin\bin\bash.exe --login -i -c <cmd>
note: you may use apache commons exec to lauch an external command from java
Use ProcessBuilder from Java:
http://download.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html
You will need to make sure your path/environment is set up properly, but that depends on your machine and set up.
Also, note that many cygwin "capabilities" (e.g., less, awk, sed, etc) are simply binaries (executables) that you can call directly -- no need for the bash shell to facilitate access to those. Look at the actual files in wherever your bin folder is (usually c:/cygwin/bin) and try calling those directly from ProcessBuilder. If you need to actually leverage the shell (e.g., pipes, variables, globbing, etc) then that's a different story -- you would then integrate with the bash.exe file itself (check the man page for usage info).