java.lang.NoClassDefFoundError: io/ реактив / объекты / субъект при создании jar в Intellij Idea (gradle + JavaFX 11)
Я использую приложение с JavaFX 11 (OpenFX). Приложение написано в IntellijIdea и построено с Gradle. При запуске в IDE все ок. При сборке jar он собирается успешно, но когда я пытаюсь его выполнить, я получаю сообщение об ошибке:
Exception in thread "main" java.lang.NoClassDefFoundError: io/reactivex/subjects/Subject
Для создания jar я использую плагин onslip.gradle-one-jar. Мой gradle следующий:
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'
}
Для создания банки я запускаю задание awesomeFunJar.
2 ответа
Основная проблема в вашей сборке связана с тем, как вы определяете зависимости с implementation
(не compile
больше), в то время как с другой стороны, вы строите свою банку на основе configurations.compile
,
поскольку implementation
а также compile
не то же самое, configurations.compile
содержит только классы вашего проекта, а не сторонние зависимости (включая JavaFX).
Запуск задачи сборки приведет к созданию очень маленькой жирной банки размером 3 КБ. Очевидно, что этот jar пропускает все классы из зависимостей.
Решение
Замените в своем фляге задачу configurations.compile
с configurations.compileClasspath
:
jar {
from { configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) } }
manifest {
attributes 'Main-Class': 'jetliner.Main'
}
}
Бежать ./gradlew build
создать толстый файл (около 23 МБ с заданными зависимостями), который можно запустить с помощью:
java -jar build/libs/myproject.jar
Или беги ./gradlew awesomeFunJar
для создания аналогичной жирной банки (21 МБ), которая работает с:
java -jar build/libs/myproject-standalone.jar
В обоих случаях io.reactivex.rxjava2
зависимости включены.
Примечание 1: я раньше не использовал этот плагин gradle-one-jar, и я не вижу какого-либо существенного преимущества в использовании пользовательского загрузчика, все, что я вижу, это то, что для образца helloFX его загрузка занимает слишком много времени, по сравнению обычная толстая банка.
Если вы используете его, потому что толстая банка не работает, может быть, вам нужен Launcher
класс, как объяснено здесь:
public class Launcher {
public static void main(String[] args) {
Main.main(args);
}
}
а затем заменить основной класс на jetliner.Launcher
,
Примечание 2: плагин JavaFX (последняя версия 0.0.7) использует implementation
и он заботится о добавлении зависимостей JavaFX, чтобы вы могли упростить файл сборки:
plugins {
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.7'
id 'com.github.onslip.gradle-one-jar' version '1.0.5'
}
repositories {
jcenter()
}
dependencies {
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.Launcher'
jar {
manifest {
attributes 'Main-Class': 'jetliner.Launcher'
}
from {
configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
}
task awesomeFunJar(type: OneJar) {
mainClass = 'jetliner.Main'
}
У меня была такая же ошибка при выполнении расширенияReports.java
, я исправил это. Я просто импортировалrxjava3.jar
иreactive.jar
в проект. Это решило мою ошибку