通过 jpackage 打包无法找到或加载 main class

Packaging via jpackage Could not find or load main class

使用 jpackage 我无法在 macOS 上获得 pkg 到 运行。安装按预期进行,但是当我启动已安装的应用程序时,它启动然后立即停止。

尝试通过 CLI 启动它并抛出

Error: Could not find or load main class com.example.Application
Caused by: java.lang.ClassNotFoundException: com.example.Application

我已将 MainClass 参数作为 com.example.Application 传递,我可以在 Contents/app/example.jar 下的安装包中看到它。

使用 Gradle 插件 id "org.panteleyev.jpackageplugin" version "1.3.1" 构建本机安装程序:

def os = org.gradle.internal.os.OperatingSystem.current()
def pkgType = os.windows ? 'msi' : os.linux ? 'deb' : 'pkg'
def inputDir = "$buildDir/input"

task copyDependencies (type: Copy) {
    from configurations.runtimeClasspath
    into inputDir
}

task copyJar (type: Copy) {
    from tasks.jar
    into inputDir
}

jpackage {
    dependsOn clean
    dependsOn bootJar
    dependsOn copyDependencies
    dependsOn copyJar

    type = pkgType

    input = inputDir
    destination = "$buildDir/dist"

    appName = 'Example'
    vendor = 'com.example'

    mainJar = tasks.jar.getArchiveFileName().get()
    mainClass = 'com.example.Application'

    javaOptions = ['-Dfile.encoding=UTF-8']
}

通过 IntelliJ/via CLI 启动 jar 运行 就可以了。

我还需要在这里做什么?

由于我正在尝试 运行 一个 Spring 启动应用程序,诀窍是不要像通常那样尝试启动主程序 class 而是使用org.springframework.boot.loader.JarLauncher

Spring 团队

blog post 中对此进行了更恰当的解释

所以 Springboot 的完整工作示例如下所示:

plugins {
    id 'org.springframework.boot' version '2.6.0-SNAPSHOT'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'org.panteleyev.jpackageplugin' version '1.3.1'

    id 'application'
}

group = 'space.forloop'
version = '1.0.6'

compileJava.options.encoding = 'UTF-8'
compileTestJava.options.encoding = 'UTF-8'
javadoc.options.encoding = 'UTF-8'


repositories {
    mavenCentral()
    maven { url 'https://repo.spring.io/milestone' }
    maven { url 'https://repo.spring.io/snapshot' }
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
}

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17)
    }
}

application {
    mainClass = 'com.example.Application'
    applicationDefaultJvmArgs = ["-Dfile.encoding=UTF-8"]
}

bootJar {
    manifest {
        attributes 'Implementation-Version': "${project.version}"
        attributes 'Implementation-Title': "${project.name}"
    }
}

// Not required but useful if you want to configure a little more.
def os = org.gradle.internal.os.OperatingSystem.current()
def pkgType = os.windows ? 'msi' : os.linux ? 'deb' : 'pkg'

jpackage {
    dependsOn "bootJar"

    type = pkgType

    input = "${buildDir}/libs"
    destination = "${buildDir}/dist"

    appName = 'Example'
    vendor = 'com.example'

    mainJar = bootJar.archiveFileName.get()
    mainClass = "org.springframework.boot.loader.JarLauncher"

    javaOptions = ['-Dfile.encoding=UTF-8']

    macPackageName = bootJar.archiveBaseName.get()
}