I am struggling to make JavaFX project to Executabel JAR fail. Instead of JAR file I get Zip archive file

56 Views Asked by At

I am creating a project on JavaFX and using Gradle (I use IntelliJ IDEA). The project is ready and runs more or less like I'd like it to. Now as I tried to make it a executable for more convinient use I found instructions that said I first need an executable JAR file. Making JAR file I get Zip archive file instead. In IntelliJ it shows that I have JAR file but if I open it in explorer it has only ZIP file and if I try to run my JAR on cmd it says there is no .jar files. Created JAR in IntelliJ ZIP arcihive file in explorer

Chat GPD suggested that there is a problem in Build.Gradle file but if I changed it as it told me to nothing changed.

1

There are 1 best solutions below

0
David Weber On

Please check First:

  • Your created file has the extension .jar
  • Your OS opens .jar files with a JRE and not with your zip app.

Solution for a modular app:

If you have a modular app, you must create a native package (exe, msi,...) with jpackage or jlink. You won't get happy without that. If you create the JavaFX application with IntelliJ, there is already a Gradle task defined for doing exactly this.

Solution for a non-modular app:

First, your main class mustn't extend from another class. This will not work.

Second, you must create a fat JAR which contains all needed dependencies.

Here is an example of a working build.gradle file including a task which can perfectly build the executable JAR:

plugins {
    id 'java'
    id 'application'
    id 'org.openjfx.javafxplugin' version '0.0.14'
}

group 'com.wedasoft'
version '1.0.0'

repositories {
    mavenLocal()
    mavenCentral()
}

ext {
    javaFxVersion = '17.0.8'
    junitVersion = '5.10.0'
    assertJVersion = '3.24.2'
    mainClassNameParam = 'your.groupId.javafxappnonmodular.MainApplicationLauncher'
}

//noinspection GroovyUnusedAssignment
mainClassName = "${mainClassNameParam}"
//noinspection GroovyUnusedAssignment
sourceCompatibility = '17'
//noinspection GroovyUnusedAssignment
targetCompatibility = '17'

tasks.withType(JavaCompile) {
    options.encoding = 'UTF-8'
}

javafx {
    version = "${javaFxVersion}"
    modules = ['javafx.controls', 'javafx.fxml']
}

dependencies {
    testImplementation("org.junit.jupiter:junit-jupiter-api:${junitVersion}")
    testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${junitVersion}")
    testImplementation("org.assertj:assertj-core:${assertJVersion}")
}

test {
    useJUnitPlatform()
}

task createCustomFatJar(type: Jar) {
    manifest {
        attributes 'Main-Class': "${mainClassNameParam}"
    }
    duplicatesStrategy = DuplicatesStrategy.EXCLUDE
    from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } }
    with jar
}

If you can't get it to work, you can download a preconfigured and full working template project from my GitHub and edit it to your needs:

https://github.com/davidweber411/javafx-JavaFxAppGradleNonModular

If it helped you, I would appreciate a star!

Additional information:

Note, that you need to have an according JDK installed.