I am running some app with JavaFX 11 (OpenFX). The app is written in IntellijIdea and built with gradle. When running in IDE everything's ok. When building a jar it builds successfully but when I try to execute it I get an error:
Exception in thread "main" java.lang.NoClassDefFoundError: io/reactivex/subjects/Subject
To build a jar I use onslip.gradle-one-jar plugin. My gradle is the following:
plugins {
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.5'
id 'com.github.onslip.gradle-one-jar' version '1.0.5'
}
repositories {
mavenCentral()
}
dependencies {
implementation "org.openjfx:javafx-base:11:win"
implementation "org.openjfx:javafx-graphics:11:win"
implementation "org.openjfx:javafx-controls:11:win"
implementation "org.openjfx:javafx-fxml:11:win"
implementation 'com.jfoenix:jfoenix:9.0.8'
implementation group: 'commons-validator', name: 'commons-validator', version: '1.6'
implementation group: 'commons-io', name: 'commons-io', version: '2.6'
implementation group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '3.141.59'
implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.8.1'
implementation group: 'com.sun.mail', name: 'javax.mail', version: '1.6.2'
implementation group: 'io.reactivex.rxjava2', name: 'rxjava', version: '2.2.5'
testImplementation group: 'junit', name: 'junit', version: '4.12'
}
javafx {
modules = [ 'javafx.controls', 'javafx.fxml' ]
}
mainClassName = 'jetliner.Main'
jar {
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
manifest {
attributes 'Main-Class': 'jetliner.Main'
}
}
task awesomeFunJar(type: OneJar) {
mainClass = 'jetliner.Main'
}
For jar building I run awesomeFunJar task.
The main problem you have in your build is related to how you define the dependencies with
implementation(notcompileanymore), while on the other hand, you build your jar based onconfigurations.compile.Since
implementationandcompileare not the same,configurations.compilecontains only the classes of your project, not the third party dependencies (including JavaFX).Running the build task will generate a very small fat jar of 3 KB. Obviously this jar misses all the classes from the dependencies.
Solution
Replace in your jar task
configurations.compilewithconfigurations.compileClasspath:Run
./gradlew buildto generate a fat jar (around 23 MB with the given dependencies), that can be run with:Or run
./gradlew awesomeFunJarto produce a similar fat jar (21 MB), that runs with:In both cases, the
io.reactivex.rxjava2dependencies are included.Note 1: I haven't used this gradle-one-jar plugin before, and I don't see any major advantage in having the custom loader, all I see is that for a helloFX sample takes really too long to load it compare with the regular fat jar.
If you use it because the fat jar doesn't run, maybe you need a
Launcherclass, as explained here:and then replace the mainClass with
jetliner.Launcher.Note 2: The JavaFX plugin (latest version 0.0.7) uses
implementation, and it takes care of adding the JavaFX dependencies, so you can simplify the build file: