e_v_e
e_v_e

Reputation: 631

Spring Boot & WinRun4J for Windows Service JAR: Service launch class outside BOOT-INF folder

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.

Upvotes: 2

Views: 1062

Answers (1)

Philippe
Philippe

Reputation: 4158

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

Upvotes: 3

Related Questions