Showing posts with label windows service. Show all posts
Showing posts with label windows service. Show all posts
Monday, February 23, 2015
Spring boot 1.4 run as windows service Procrun
The challenge was starting spring boot application as windows service. I spent a long time searching on the Internet the solution but I didn't find it.
My solution was the following.
First I created an application using start.spring.io
Then, I created a project to which I added spring-boot-loader dependency
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-loader</artifactId>
<scope>provided</scope>
</dependency>
because of the need to extend the JarLauncher class.
Spring boot provides a special launcher that changes the java behaviour class loader. The class org.springframework.boot.loader.JarLauncher creates a special class loader and boostraps the application.
Since I wanted to launch the application as a window service, I chose Procrun as service manager.
Procrun needs two start and stop methods or one method with string array parameter (see procrun project for more details). Therefore I created a Bootsrap class that extended JarLauncher and implemented the methods that Procrun needs.
public class Bootstrap extends JarLauncher {
private static ClassLoader classLoader = null;
private static Bootstrap bootstrap = null;
protected void launch(String[] args, String mainClass, ClassLoader classLoader, boolean wait)
throws Exception {
// spring boot 1.2 Runnable runner = createMainMethodRunner(mainClass, args, classLoader);
// spring boot 1.2 Thread runnerThread = new Thread(runner);
Thread runnerThread = new Thread(() -> {
try {
createMainMethodRunner(mainClass, args, classLoader).run();
}
catch(Exception ex) {}
});
runnerThread.setContextClassLoader(classLoader);
runnerThread.setName(Thread.currentThread().getName());
runnerThread.start();
if (wait == true) {
runnerThread.join();
}
}
public static void start (String []args) {
bootstrap = new Bootstrap ();
try {
JarFile.registerUrlProtocolHandler();
classLoader = bootstrap.createClassLoader(bootstrap.getClassPathArchives());
bootstrap.launch(args, bootstrap.getMainClass(), classLoader, true);
}
catch (Exception ex) {
ex.printStackTrace();
System.exit(1);
}
}
public static void stop (String []args) {
try {
if (bootstrap != null) {
bootstrap.launch(args, bootstrap.getMainClass(), classLoader, true);
bootstrap = null;
classLoader = null;
}
}
catch (Exception ex) {
ex.printStackTrace();
System.exit(1);
}
}
public static void main(String[] args) {
String mode = args != null && args.length > 0 ? args[0] : null;
if ("start".equals(mode)) {
Bootstrap.start(args);
}
else if ("stop".equals(mode)) {
Bootstrap.stop(args);
}
}
}
In the spring boot application class I changed the main method with:
private static ApplicationContext applicationContext = null;
public static void main(String[] args) {
String mode = args != null && args.length > 0 ? args[0] : null;
if (logger.isDebugEnabled()) {
logger.debug("PID:" + ManagementFactory.getRuntimeMXBean().getName() +
" Application mode:" + mode + " context:" + applicationContext);
}
if (applicationContext != null && mode != null && "stop".equals(mode)) {
System.exit(SpringApplication.exit(applicationContext, new ExitCodeGenerator() {
@Override
public int getExitCode() {
return 0;
}
}));
}
else {
SpringApplication app = new SpringApplication(TestProcrunApplication.class);
applicationContext = app.run(args);
if (logger.isDebugEnabled()) {
logger.debug("PID:" + ManagementFactory.getRuntimeMXBean().getName() +
" Application started context:" + applicationContext);
}
}
}
Then, I installed the service with prunsrv.exe
prunsrv.exe //IS//test-procrun --DisplayName="test-procrun" --Description="test-procrun" --Startup=auto --Install=%CD%\prunsrv.exe --Jvm=auto --Classpath=%CD%..\target\test-procrun-0.0.1-SNAPSHOT.jar --StartMode=jvm --StartClass=it.test.procrun.Bootstrap --StartMethod=start --StartParams=start --StopMode=jvm --StopClass=it.test.procrun.Bootstrap --StopMethod=stop --StopParams=stop --StdOutput=auto --StdError=auto --LogPath=%CD% --LogLevel=Debug
source code spring boot 1.2,1.3
source code spring boot 1.4
Subscribe to:
Posts (Atom)


