1

I want to run an Spring Boot Application as a Windows Service using WinRun4J. It doesn't work since WinRun4J is unable to find the main class. I noticed that it is because the spring-boot-maven-plugin collect the sources inside a BOOT-INF folder and it can't access to the classes there. This is the error trace:

[info] Registering natives for Native class
[info] Registering natives for FFI class
 [err] Could not find service class
 [err] Failed to initialise service: 1
java.lang.NoClassDefFoundError: SpringBootLauncherService
Caused by: java.lang.ClassNotFoundException: SpringBootLauncherService
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)

Is there a way to generate the Spring Boot executable jar with the desired class outside the BOOT-INF folder? Or maybe do you know a full example using Spring Boot and WinRun4J?

The generated jar by the spring-boot-maven-plugin has the following structure:

myapp-0.0.1-SNAPSHOT.jar
|--- org: Spring Boot Loader classes
|--- META-INF: maven/ & MANIFEST-MF
|--- BOOT-INF: lib/ & classes/

And I believe that I need something like this:

myapp-0.0.1-SNAPSHOT.jar
|--- org: Spring Boot Loader classes
|--- META-INF: maven/ & MANIFEST-MF
|--- BOOT-INF: lib/ & classes/
|--- SpringBootLauncherService.class

I would appreciate any help.

e_v_e
  • 478
  • 3
  • 16

1 Answers1

3

I was able to make it work as follows.

  • I used the bootRepackage classifier property to force Spring Boot to make 2 JARs: one with the Spring Boot structure, and the other a normal JAR that can be used for other purposes, like integration with WinRun4J for example. This is explained fairly well in Use a Spring Boot application as a dependency
  • I extracted the lib from the executable JAR and added the folder to the classpath in the INI file for WinRun4J. classpath.1=the-springboot-app.jar classpath.2=./lib/*
  • Still in the INI file, I added vmarg.1=-Dloader.main=the.springboot.app.Application so that the SpringBootLauncherService class using the SpringBoot PropertiesLaucher can resolve the loader class.
  • The service.class is set in the INI to service.class=the.springboot.app.SpringBootLauncherService
Philippe
  • 4,088
  • 4
  • 44
  • 49
  • 1
    This being said, I also tried `winsw` and found it to be much simpler. It starts the Spring Boot application the same way I would on the command line, with `java -jar my-app.jar`. I would recommend it you take a look at it as a very good alternative to WinRun4J. See http://docs.spring.io/spring-boot/docs/current/reference/html/deployment-install.html#deployment-windows. – Philippe Feb 28 '17 at 15:14
  • 1
    You're exactly right about `winsw`. Worked like a charm for my app -- thanks. – Blake Nov 14 '17 at 16:27