Search code examples
gradlejarjava-11javafx-11

JavaFX 11 : Create a jar file with Gradle


I am trying to upgrade a JavaFX project from the 8 Java version to the 11 version. It works when I use the "run" Gradle task (I followed the Openjfx tutorial), but when I build (with the "jar" Gradle task) and execute (with "java -jar") a jar file, the message "Error: JavaFX runtime components are missing, and are required to run this application" appears.

Here is my build.gradle file :

group 'Project'
version '1.0'
apply plugin: 'java'
sourceCompatibility = 1.11

repositories {
    mavenCentral()
}

def currentOS = org.gradle.internal.os.OperatingSystem.current()
def platform
if (currentOS.isWindows()) {
    platform = 'win'
} else if (currentOS.isLinux()) {
    platform = 'linux'
} else if (currentOS.isMacOsX()) {
    platform = 'mac'
}
dependencies {
    compile "org.openjfx:javafx-base:11:${platform}"
    compile "org.openjfx:javafx-graphics:11:${platform}"
    compile "org.openjfx:javafx-controls:11:${platform}"
    compile "org.openjfx:javafx-fxml:11:${platform}"
}

task run(type: JavaExec) {
    classpath sourceSets.main.runtimeClasspath
    main = "project.Main"
}

jar {
    manifest {
        attributes 'Main-Class': 'project.Main'
    }
    from {
        configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
    }
}

compileJava {
    doFirst {
        options.compilerArgs = [
                '--module-path', classpath.asPath,
                '--add-modules', 'javafx.controls,javafx.fxml'
        ]
    }
}

run {
    doFirst {
        jvmArgs = [
                '--module-path', classpath.asPath,
                '--add-modules', 'javafx.controls,javafx.fxml'
        ]
    }
}

Do you know what I should do ?


Solution

  • [Edit: For the latest versions of JavaFX, please check my second answer]

    If someone is interested, I found a way to create jar files for a JavaFX11 project (with Java 9 modules). I tested it on Windows only (if the application is also for Linux, I think we have to do the same steps but on Linux to get JavaFX jars for Linux).

    I have a "Project.main" module (created by IDEA, when I created a Gradle project) :

     src
     +-- main
     |   +-- java
         |   +-- main
             |   +-- Main.java (from the "main" package, extends Application)
         |   +-- module-info.java
     build.gradle
     settings.gradle
     ...
    

    The module-info.java file :

    module Project.main {
        requires javafx.controls;
        exports main;
    }
    

    The build.gradle file :

    plugins {
        id 'java'
    }
    
    group 'Project'
    version '1.0'
    ext.moduleName = 'Project.main'
    sourceCompatibility = 1.11
    
    repositories {
        mavenCentral()
    }
    
    def currentOS = org.gradle.internal.os.OperatingSystem.current()
    def platform
    if (currentOS.isWindows()) {
        platform = 'win'
    } else if (currentOS.isLinux()) {
        platform = 'linux'
    } else if (currentOS.isMacOsX()) {
        platform = 'mac'
    }
    dependencies {
        compile "org.openjfx:javafx-base:11:${platform}"
        compile "org.openjfx:javafx-graphics:11:${platform}"
        compile "org.openjfx:javafx-controls:11:${platform}"
    }
    
    task run(type: JavaExec) {
        classpath sourceSets.main.runtimeClasspath
        main = "main.Main"
    }
    
    jar {
        inputs.property("moduleName", moduleName)
        manifest {
            attributes('Automatic-Module-Name': moduleName)
        }
    }
    
    compileJava {
        inputs.property("moduleName", moduleName)
        doFirst {
            options.compilerArgs = [
                    '--module-path', classpath.asPath,
                    '--add-modules', 'javafx.controls'
            ]
            classpath = files()
        }
    }
    
    task createJar(type: Copy) {
        dependsOn 'jar'
        into "$buildDir/libs"
        from configurations.runtime
    }
    

    The settings.gradle file :

    rootProject.name = 'Project'
    

    And the Gradle commands :

    #Run the main class
    gradle run
    
    #Create the jars files (including the JavaFX jars) in the "build/libs" folder
    gradle createJar
    
    #Run the jar file
    cd build/libs
    java --module-path "." --module "Project.main/main.Main"