beryx/badass-jlink-plugin

secondary Launcher fails with application main class missing

xzel23 opened this issue · 9 comments

xzel23 commented

I try to create a secondary launcher for my JavaFX app. The class com.dua3.docdiff.app.fx.AppMain starts a JavaFX application, com.dua3.docdiff.app.cli.Main is a command line tool that does not use JavaFX. Both classes are in the same module.

I have this in my Kotlin-DSL build file:

    launcher {
        name = "docdiff"
        noConsole = true
        mainClass.set("com.dua3.docdiff.app.fx.AppMain")
        jvmArgs = listOf("-Xms512m", "-Xmx4g", "-XX:+UseG1GC")
    }

    secondaryLauncher {
        name = "docdiffcli"
        noConsole = false
        mainClass.set("com.dua3.docdiff.app.cli.Main")
        jvmArgs = listOf("-Xms512m", "-Xmx2g", "-XX:+UseG1GC")
    }

When I run ./gradlew jpackage, I get the following error:

[10:19:20.369] Anwendungspackage DocDiff.app wird in /Users/axelhowind/IdeaProjects/doc-app/docdiff/app/build/jpackage erstellt
[10:19:20.431] java.lang.RuntimeException: jdk.jpackage.internal.ConfigException: Fehler: Hauptanwendungsklasse fehlt

(This is the localized message, it should translate to "application main class missing".)

Both launchers work if I comment out the other launcher (and replace secondaryLauncher with launcher).

I have not idea what could be wrong since I clearly set mainClass for both launchers.

The versions I am using are Gradle 8.4 and Java 21.0.1, jlink plugin version 3.0.0.

xzel23 commented

OK, after endless headaches (I'm neither an expert in Groovy nor in Kotlin) I found a workaround (tested with version 3.0.0 of the plugin).

Replace the secondaryLauncher block with this:

    val sld = SecondaryLauncherData("docdiffcli")
    sld.mainClass = "com.dua3.docdiff.app.cli.Main"
    sld.noConsole = false
    sld.jvmArgs = listOf("-Xms512m", "-Xmx2g", "-XX:+UseG1GC")
    secondaryLaunchers.add(sld)

I still don't get my head around what exactly is happaning here. But in IntelliJ I can see that the secondaryLauncher expects a LauncherData instance:

image

LauncherData does not have a member called mainclass. So probably something needs to be changed to make secondaryLauncher expect SecondaryLauncherData instead of LauncherData.

Is it possible this either a bug or misunderstanding with the Kotlin DSL? I'm not able to reproduce this issue by adding these lines to an app built with Groovy DSL:

secondaryLauncher {
    name = "docdiffcli"
    noConsole = false
    mainClass = "com.dua3.docdiff.app.cli.Main"
    jvmArgs = ["-Xms512m", "-Xmx2g", "-XX:+UseG1GC"]
}
xzel23 commented

Yes, seems like something that works different in the Kotlin DSL. However my build file is rather big, with version catalog and all, so I'd rather not go back to groovy (and honestly I don't like Groovy because there are too many ambiguities).

Could you provide a repository with a minimal reproducible example?

xzel23 commented

I have created a minimal example that exposes the problem.

secondaryLauncher.zip

xzel23 commented

The solution with this as org.beryx.jlink.data.SecondaryLauncherData does not seem to work either in the minimal example.

@airsquared I finally had time to look into this and have prepared a PR for this. Please apply.

Thanks! Merged