How to add JNI hooks to one jar generated by Spring Boot

590 views Asked by At

I am using Spring Boot gradle plugin (org.springframework.boot) to generate the "one" jar. It works well when I run java -jar app.jar - does exactly what's expected. However, this application should be running as a daemon using Apache Commons Daemon via JNI. Previous version of this app was built on top of a home-made framework, I had start and shutdown methods in the main class I could specify in the daemon config.

I saw that Main-Class becomes org.springframework.boot.loader.JarLauncher, which does not have a start and shutdown methods implemented anywhere in it or it's superclasses. There is a launch method, but I think that can only work for running the jar with java -jar.

Here is the manifest file (redacted) generated by the gradle plugin and contents of the decompiled one jar:

Manifest-Version: 1.0
Start-Class: com.company.myapp.Application
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Spring-Boot-Version: 1.5.6.RELEASE
Main-Class: org.springframework.boot.loader.JarLauncher

enter image description here

My question then is: can I configure this gradle plugin to add JNI hooks methods so that they run my app's main class correctly? I know there is a Shadow plugin for Gradle to make the "uber" jar, and I can also forgo creating the "uber" jar and distribute in a lib/ directory (it's a desktop application). However, if Spring Boot developers thought about it and there is a way to do this, I'd rather use that.

1

There are 1 answers

2
SlaterCodes On

So I am using StartMode=Java instead of jvm and it seems to work alright. The only problem is I don't think Spring Boot is gracefully shutting down but I can live with that for now.

MyApp.exe //IS//MyApp --Install="C:\appData\Programs\MyApp\MyApp.exe" ^
 --Startup=auto --StartMode=Java ^
 --JavaHome="C:\appData\Programs\Java" ^
 --Classpath="C:\appData\Programs\MyApp\MyApp.jar" ^
 --StartClass="org.springframework.boot.loader.JarLauncher" ^
 --ServiceUser="MyAppUser --ServicePassword="xxxxxx" ^
 --LogPath="C:\appData\Programs\MyApp\logs" ^
 --StartPath="C:\appData\Data\MyApp" ^
 --StopTimeout=30

I renamed the exe files to match my app name "MyApp" and I used the 64-bit exe with a 64-bit JVM on Windows Server. I got some weird DCOM errors with the Service User in Windows Event Viewer under System, but a few restarts and making sure my service user had permissions on this folder fixed it up.