fvarrui / JavaPackager

:package: Gradle/Maven plugin to package Java applications as native Windows, MacOS, or Linux executables and create installers for them.
GNU General Public License v3.0
1.05k stars 132 forks source link

Packaging with JavaFX #372

Closed dresch86 closed 6 months ago

dresch86 commented 11 months ago

I have been looking for an example of how to package JavaFX with this plugin. I added the following to the gradle.build

task packageMyApp(type: io.github.fvarrui.javapackager.gradle.PackageTask, dependsOn: build) {
    // mandatory
    mainClass = 'org.ose.scheduler.MyAppLauncher'

    // optional
    bundleJre = true
    generateInstaller = true
    administratorRequired = false

    additionalModulePaths = [file("$System.env.PATH_TO_FX/lib")]
    additionalModules = ['javafx.base', 'javafx.controls', 'javafx.graphics', 'javafx.fxml']
}

But it looks like the bundled JRE is missing all the JavaFX .dll's. When I copy them manually, the app.exe works fine. Without copying the ,dll's, the executable does not work. I am running on Windows.

ilacc1 commented 11 months ago

Hey there, I fell into this pit too! At issue is that JavaFX jars are platform-specific.

Don't know with Gradle, but with maven, I've solved it with profiles and classifiers. Here is an example:


<!-- Set up profiles -->
  <profiles>
      <profile>
        <id>win</id>
        <activation>
          <os>
            <family>windows</family>
          </os> 
        </activation> 
        <properties>
          <os.label>win</os.label>
          <os.libs>libs</os.libs>
          <javafx.platform>win</javafx.platform>
        </properties>
      </profile>
      <profile>
        <id>mac</id>
        <activation>
          <os>
            <family>mac</family>
          </os> 
        </activation> 
        <properties>
          <os.label>mac</os.label>
          <os.libs>Java/libs</os.libs>
          <javafx.platform>mac</javafx.platform>
        </properties>
      </profile>
      <profile>
        <id>linux</id>
        <activation>
          <os>
            <family>unix</family>
            <name>Linux</name>
          </os> 
        </activation> 
        <properties>
          <os.label>linux</os.label>
          <os.libs>libs</os.libs>
          <javafx.platform>linux</javafx.platform>
        </properties>
      </profile>
  </profiles>

<!-- Java FX Dependencies with classifiers -->

<dependencies>
   <dependency>
    <groupId>org.openjfx</groupId>
    <artifactId>javafx-base</artifactId>
    <version>${jfx.version}</version>
    <classifier>${os.label}</classifier>
  </dependency>
   <dependency>
    <groupId>org.openjfx</groupId>
    <artifactId>javafx-fxml</artifactId>
    <version>${jfx.version}</version>
    <classifier>${os.label}</classifier>
  </dependency>
   <dependency>
    <groupId>org.openjfx</groupId>
    <artifactId>javafx-graphics</artifactId>
    <version>${jfx.version}</version>
    <classifier>${os.label}</classifier>
  </dependency>
</dependencies>

Hope this helps!

lhDream commented 11 months ago

What versions of java and javafx are used? Maybe you can refer to the following configuration.

java version: 17
javafx verison: 17.0.2
plugins {
    kotlin("jvm") version "1.6.21"
    id("application")
    id("org.openjfx.javafxplugin").version("0.0.10")
}
buildscript{
    repositories {
        mavenCentral()
        gradlePluginPortal()
    }
    dependencies {
        classpath("io.github.fvarrui:javapackager:1.7.5")
    }
}
apply(plugin = "io.github.fvarrui.javapackager.plugin")
tasks.register("trlh",io.github.fvarrui.javapackager.gradle.PackageTask::class.java){
    mainClass = "your mainClass"
    displayName = "your displayName "
    appName = "your appName"
    isBundleJre = true
    isCustomizedJre = false
    isCopyDependencies = true
    isGenerateInstaller = true
    platform = io.github.fvarrui.javapackager.model.Platform.auto
    // vm param
    vmArgs = ArrayList<String?>().apply {
        this.add("-Xms256M")
    }
    // SSL 
//    if(additionalModules == null){
//        additionalModules = ArrayList<String>()
//    }
//    additionalModules.apply {
//        this.add("jdk.crypto.ec")
//    }

    winConfig(null).apply {
        this.headerType = io.github.fvarrui.javapackager.model.HeaderType.console
        isGenerateInstaller = true
        isGenerateSetup = true
        isGenerateMsi = false
        isGenerateMsm = false
        this.isDisableDirPage = false
        this.isDisableFinishedPage = false
        this.isDisableRunAfterInstall = false
    }

    linuxConfig(null).apply {
        isGenerateInstaller = true
        isGenerateDeb = true
        isGenerateAppImage = false
        isGenerateRpm = false
    }
}

javafx{
    version = "17.0.2"
    modules("javafx.base","javafx.controls","javafx.web")
}
lhDream commented 11 months ago

@ilacc1 @dresch86 You can try this demo project https://github.com/lhDream/demo/tree/main/java17Demo/javafxDemo

dresch86 commented 11 months ago

I am using Java 20.0.2 and the matching JavaFX version. I found out what my problem was. For some reason, even though I added the Gradle dependencies, the mods weren't getting included. I fixed that by manually downloading the jmods, setting the path as an environment variable, and including them like this....

additionalModulePaths = [file("$System.env.PATH_TO_FX_MODS")]

Doing it this way adds some work to my CircleCI build, but it works! The repo is here but still undergoing development.