Creating a Unix daemon or NT Service in 100% Java

Hello all,

had a hard time deciding where to post this question, but finally decided to do it here because it seems to relate to the lifecycle of the JVM.

I am writting a server (SocketServer-handler thread implementation) and right now it has all been a breeze, it starts, binds to its port, listens, creates sockets and threads to handle the communication and sits doing this in a loop forever until stop.

it's your regular server with the only difference that it runs on the foreground as user and not on the background as a daemon, like all good servers.

At first I thought making it a daemon thread would solve the problem, but it turns out daemon threads are only 'daemonic' relative to their amin thread and get killed when there are no more normal threads to service.

After doing some research I've found at least five different ways of doing this but all involve writting os dependent code in C, C++ or VC++, which has to horrible drawbacks: platform dependency (writting four or five implementation of a java program is an oximoron) and that I don't know C or C++ yet.

I can believe that Java has no way to preform this basic and very useful feature. Are all Java servers hybrids of Java and other languages?

Any help will be inmenselly appreciated, and credit given on the software and future article (which I will write to help any other lost souls trying to accomplish this seemingly impossible task, like me)

TIA

depeupleur

[1512 byte] By [depeupleur] at [2007-9-26 5:44:04]
# 1
>I can believe that Java has no way to preform this basic and very useful feature. There is no way. All solutions involve some other OS dependent stuff.
jschell at 2007-7-1 14:03:16 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 2

Hi jschell, thanks for your answer.

That's strange, I thought the JVM was precisely an abstraction to let Java be built on top of diverse OS. Is it too low level for the JVM to handle.

I'm also thinking of implementing it as a Servlet, if it can't be a daemon, it might be useful to use other daemons instead, like a web container.

Do you have any other suggestions.

Thanks in advance,

depeupleur at 2007-7-1 14:03:16 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 3

Java is not a solution for everything. For instance, it is unlikely to be the best choice for a device driver.

Since you already have the functionality written basically all you need to do is the install part - it sounds like for your process that is the only OS dependent part. So wrap in the OS dependent stuff to install it and go from there.

jschell at 2007-7-1 14:03:16 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 4

For UNIX you need just create a startup srcipt and place it to inittab (for AIX) or to /etc/rc directory (for Solaris) and it will be enough to start java program at system start-up. Also for NT or Win2k you can use RunAsService services (in Resource Kit for NT 4 and default in Win2k) which do the same things - to start application as servie. There is only problem with restarting your program when it crashes.

Sincerely,

Sergei

Sergegu at 2007-7-1 14:03:16 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 5
Very nice solution Sergegu, thanks. Would that start up script in UNIX have a way to make the process a proper daemon, do I send it to the background with &? Is there another way?If you can post an example I'd be really greatful.Thanks for your help.
depeupleur at 2007-7-1 14:03:16 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 6

Here is a startup script (in /etc/rc.d/init.d/jchat on linux RH 7, and enabled with chkconfig)

##############################################

#!/bin/sh

#

# Startup script for the Java chat server

#

# chkconfig: 345 99 01

# description: Chat server (Java Application).

# processname: jchat

# pidfile: /usr/local/chat/jchat.pid

###### start editing here ######

# user to run the process as:

USER=chat

# start & stop scripts

START_SCRIPT=/usr/local/chat/start_jchat.sh

STOP_SCRIPT=/usr/local/chat/stop_jchat.sh

###### stop editing here ######

start(){

$START_SCRIPT

#su - $USER -c $START_SCRIPT

}

stop(){

$STOP_SCRIPT

#su - $USER -c $STOP_SCRIPT

}

# See how we were called.

case "$1" in

start)

start

;;

stop)

stop

;;

restart)

stop

sleep 3s

start

;;

*)

echo "Usage: $0 {start|stop|restart}"

exit 1

esac

exit 0

##############################################

Here is start_jchat.sh

##############################################

#!/bin/sh

# java location

JAVA=/usr/local/jdk/bin/java

# jar archive:

JARARCHIVE=/usr/local/chat/jchat/com.romandie.chat.jar

# postgresql driver

PGSQLDRIVER=/usr/local/pgsql/share/java/postgresql.jar

# pid file

PIDFILE=/usr/local/chat/jchat.pid

# common log file:

COMMON_LOG=/usr/local/chat/logs/jchat-common_log

#error log file:

ERROR_LOG=/usr/local/chat/logs/jchat-error_log

export CLASSPATH=$CLASSPATH:$PGSQLDRIVER:$JARARCHIVE

echo $CLASSPATH

echo -n "Starting: $JARARCHIVE"

$JAVA xx.xxxxxx.chat.Server 1>>$COMMON_LOG 2>> $ERROR_LOG &

echo $! > $PIDFILE

echo "OK"

##############################################

Here is stop_jchat.sh

##############################################

#!/bin/sh

# jar archive:

JARARCHIVE=/usr/local/chat/jchat/xxx.xxxxx.chat.jar

# pid file

PIDFILE=/usr/local/chat/jchat.pid

echo -n "Shutting down: $JARARCHIVE"

kill -9 `cat $PIDFILE`

echo "OK"

##############################################

hope this helps

-leo

lbouchet at 2007-7-1 14:03:16 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 7
Thanks leo. I apreciate it.
depeupleur at 2007-7-1 14:03:16 > top of Java-index,Java HotSpot Virtual Machine,Specifications...