简体   繁体   中英

How do I build a Spring Boot jarfile that systemd can execute directly as a service?

How do I build a Spring Boot jarfile that systemd can directly execute as a service?

Following the example in Installation as a systemd service , I created the following systemd service that directly executes a Spring Boot jarfile :

[Unit]
Description=CRS Self-certification Service
Documentation=
Requires=postgresql.service
After=postgresql.service

[Service]
Environment=LOADER_PATH='lib/,config/,/etc/opes/crs/selfcertification'
ExecStart=/opt/opes/crs/selfcertification/crs-selfcertification-1.0.0-SNAPSHOT.jar
Restart=always
RestartSec=10
User=crs

[Install]
WantedBy=multi-user.target

However, when starting this service, systemd complains that the jarfile is not executable:

Nov 29 10:57:59 ubuntu systemd[24109]: selfcertification.service: Failed at step EXEC spawning /opt/opes/crs/selfcertification/crs-selfcertification-1.0.0-SNAPSHOT.jar: Exec format error
Nov 29 10:57:59 ubuntu systemd[1]: selfcertification.service: Main process exited, code=exited, status=203/EXEC
Nov 29 10:57:59 ubuntu systemd[1]: selfcertification.service: Unit entered failed state.
Nov 29 10:57:59 ubuntu systemd[1]: selfcertification.service: Failed with result 'exit-code'.

The permissions of the jarfile are 755 (executable by all):

administrator@ubuntu:~$ ls -la /opt/opes/crs/selfcertification/crs-selfcertification-1.0.0-SNAPSHOT.jar
-rwxr-xr-x 1 crs selfcertification 35978778 Nov 22 17:16 /opt/opes/crs/selfcertification/crs-selfcertification-1.0.0-SNAPSHOT.jar

What changes must I make to the following Gradle build script in order to build an executable jarfile for the systemd service?

buildscript {
    ext {
        springBootVersion = '1.4.2.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'

jar {
    baseName = 'crs-selfcertification'
    version = '1.0.0-SNAPSHOT'
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories {
    mavenCentral()
}

springBoot {
    mainClass = "com.opessoftware.crs.selfcertification.Application"
    layout = "ZIP"
}

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web")
    compile("org.springframework.boot:spring-boot-starter-thymeleaf")
    compile("org.springframework.boot:spring-boot-starter-data-jpa")
    compile("org.springframework.boot:spring-boot-starter-mail")
    testCompile("org.springframework.boot:spring-boot-starter-test")
    compile group: 'org.postgresql', name: 'postgresql', version: '9.4.1208.jre7'
    compile group: 'org.apache.commons', name: 'commons-dbcp2', version: '2.1.1'
    compile group: 'junit', name: 'junit', version: '4.12'

}

Note that this service runs successfully if instead of trying to run the jarfile directly, systemd instead launches it using the Java Virtual Machine (JVM) from a shell script :

[Unit]
Description=CRS Self-certification Service
Documentation=
Requires=postgresql.service
After=postgresql.service

[Service]
Environment=LOADER_PATH='lib/,config/,/etc/opes/crs/selfcertification'
#ExecStart=/opt/opes/crs/selfcertification/crs-selfcertification-1.0.0-SNAPSHOT.jar
ExecStart=/opt/opes/crs/selfcertification/startCrsSelfCertification
Restart=always
RestartSec=10
User=crs

[Install]
WantedBy=multi-user.target

Shell script /opt/opes/crs/selfcertification/startCrsSelfCertification invokes the jarfile using the JVM:

#!/bin/sh

java -Dloader.path='lib/,config/,/etc/opes/crs/selfcertification' -jar /opt/opes/crs/selfcertification/crs-selfcertification-1.0.0-SNAPSHOT.jar

What might be missing from the Spring Boot jarfile that prevents systemd from executing the jarfile directly?

You should instruct Spring Boot to repackage your project into the fully executable form:

springBoot {
    executable = true
}

and this feature is only available for Spring Boot 1.4.0+.

Refer to http://docs.spring.io/spring-boot/docs/current/reference/html/build-tool-plugins-gradle-plugin.html#build-tool-plugins-gradle-repackage-configuration for more information.

From Spring Boot 2.X+ , use:

  bootJar {
      launchScript()
  }

Source: Executable Spring Boot 2 jar

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM