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в проект. Это решило мою ошибку

Другие вопросы по тегам