Introduction
In cases when it is needed to run application in background and to start whenever system starts then it is required to make it a service. In windows platform an application needs to have service capabilities such as start, stop and status to run it a service. For java applications this capability is not inherent and a wrapper application is needed to achieve this. Apache Commons-Daemon project is one common tool for this.
Steps
1- Java Application needs to implement org.apache.commons.daemon.Daemon interface.
public class ServiceWrapper implements Daemon {
private final static Logger logger = LoggerFactory.getLogger(ServiceWrapper.class);
private static final ServiceWrapper serviceWrapper = new ServiceWrapper();
static void main(String[] args) throws Exception {
String mode = args[0];
logger.info("ServiceWrapper main started");
if ("start".equals(mode)) {
logger.debug("ServiceWrapper starting service");
serviceWrapper.init(null);
serviceWrapper.start();
} else {
logger.debug("ServiceWrapper stopping service");
serviceWrapper.stop();
serviceWrapper.destroy();
}
}
@Override
public void init(DaemonContext daemonContext) throws DaemonInitException, Exception {
logger.info("ServiceWrapper init called");
}
@Override
public void start() throws Exception {
logger.info("ServiceWrapper start called");
Main.class.getDeclaredMethod("main", String[].class).invoke(null, (Object) null);
}
@Override
public void stop() throws Exception {
logger.info("ServiceWrapper halt called");
Main.class.getDeclaredMethod("halt").invoke(null);
}
@Override
public void destroy() {
logger.info("ServiceWrapper destroy called");
}
}
2- Add required dependecy to pom.
<dependency>
<groupId>commons-daemon</groupId>
<artifactId>commons-daemon</artifactId>
<version>1.0.15</version>
</dependency>
3- Build java application and put the output to some directory which will be called application directory. NOT: Application directory must not have space characters.
4- Download Apache Commons Daemon binaries from the link below: http://www.apache.org/dist/commons/daemon/binaries/windows/
5- Zip contains windows applications to run java application as windows service. Copy prunmgr.exe to application directory. If target jvm is X86 then copy prunsvr.exe to application directory. If target jvm is amd64 then copy prunsvr.exe from amd64 directory to application directory.
6- Now application directory looks like below:
application.jar
dependency1.jar
dependency2.jar
prunsvr.exe
prunmgr.exe
7- Lets assume service name will be somejarservice. Rename prunsvr.exe to somejarservice.jar and rename prunmgr.exe to somejarservicew.jar.
8- Now application directory looks like below:
application.jar
dependency1.jar
dependency2.jar
somejarservice.exe
somejarservicew.exe
9- Create service.bat file, this file will be used to create Windows Service firts time application is deployed to target system.
This bach file is a modification of the one that is used for tomcat.
@echo off
if "%OS%" == "Windows_NT" setlocal
set "SELF=%~dp0%service.bat"
rem Guess SERVICE_HOME if not defined
set "CURRENT_DIR=%cd%"
set "SERVICE_HOME=%cd%"
set "EXECUTABLE=%SERVICE_HOME%\somejavaservice.exe"
rem Set default Service name
set SERVICE_NAME=SomeJavaService
set PR_DISPLAYNAME=Some Java Service Description
:doInstall
rem Install the service
echo Installing the service '%SERVICE_NAME%' ...
echo Using SERVICE_HOME: "%SERVICE_HOME%"
rem Use the environment variables as an example
rem Each command line option is prefixed with PR_
set PR_DESCRIPTION=OMS PF Report Service
set "PR_INSTALL=%EXECUTABLE%"
set "PR_CLASSPATH=%SERVICE_HOME%;%SERVICE_HOME%\application.jar;%SERVICE_HOME%\dependency1.jar;%SERVICE_HOME%\dependency2.jar"
set PR_JVM=auto
set PR_STDOUTPUT=auto
set PR_STDERROR=auto
"%EXECUTABLE%" //IS//%SERVICE_NAME% ^
--StartClass com.package.ServiceWrapper ^
--StopClass com.package.ServiceWrapper ^
--Classpath %PR_CLASSPATH% ^
--StartMode jvm ^
--StopMode jvm ^
--StartParams start ^
--StopParams stop ^
--Jvm "C:\Program Files (x86)\Java\jre6\bin\client\jvm.dll" ^
--JvmMs 128 ^
--JvmMx 256
if not errorlevel 1 goto installed
echo Failed installing '%SERVICE_NAME%' service
goto end
:installed
rem Clear the environment variables. They are not needed any more.
set PR_DISPLAYNAME=
set PR_DESCRIPTION=
set PR_INSTALL=
set PR_LOGPATH=
set PR_CLASSPATH=
set PR_JVM=
echo The service '%SERVICE_NAME%' has been installed.
:end
cd "%CURRENT_DIR%
10- Now the service directory looks like below:
application.jar
dependency1.jar
dependency2.jar
somejarservice.exe
somejarservicew.exe
service.bat
11- For testing, execute service.bat. In windows 7 Go to Control Panel->Administrative Tools->View Local Services. Find “Some Java Service Description”. Click properties and start the service.
For service logs check the directory below to ensure that service starts successfully:
%SystemRoot%\System32\LogFiles\Apache
Conclusion
Now Java application will start in background with the possibility to start and end anytime and ability to run at system startup.
Comments
Post a Comment