java.lang.NoClassDefFoundError:io/reactivex/subjects/Subject在Intellij Idea中构建jar时(gradle+;JavaFX 11)

java.lang.NoClassDefFoundError:io/reactivex/subjects/Subject在Intellij Idea中构建jar时(gradle+;JavaFX 11),java,gradle,rx-java2,javafx-11,openfx,Java,Gradle,Rx Java2,Javafx 11,Openfx,我正在用JavaFX11(OpenFX)运行一些应用程序。这个应用程序是用IntellijIdea编写的,是用gradle构建的。在IDE中运行时,一切正常。当构建jar时,它会成功构建,但当我尝试执行它时,会出现错误: Exception in thread "main" java.lang.NoClassDefFoundError: io/reactivex/subjects/Subject 为了构建一个jar,我使用onslip.gradle-one-jar插件。我的成绩如下: plug

我正在用JavaFX11(OpenFX)运行一些应用程序。这个应用程序是用IntellijIdea编写的,是用gradle构建的。在IDE中运行时,一切正常。当构建jar时,它会成功构建,但当我尝试执行它时,会出现错误:

Exception in thread "main" java.lang.NoClassDefFoundError: io/reactivex/subjects/Subject
为了构建一个jar,我使用onslip.gradle-one-jar插件。我的成绩如下:

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'
}

对于jar构建,我运行awesomeFunJar任务。

构建中的主要问题是如何使用
实现定义依赖项(不再是
编译
),而另一方面,您基于
配置构建jar。编译

由于
implementation
compile
不一样,
configurations.compile
只包含项目的类,而不包含第三方依赖项(包括JavaFX)

运行构建任务将生成一个3KB的非常小的胖jar。显然,这个jar会丢失依赖项中的所有类

解决方案

替换jar任务中的
配置。用
配置编译
。编译CLASSPATH

jar {
    from { configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) } }
    manifest {
        attributes 'Main-Class': 'jetliner.Main'
    }
}
运行
/gradlew build
生成一个fat jar(在给定依赖项下大约23MB),该jar可以与以下各项一起运行:

java -jar build/libs/myproject.jar
或者运行
/gradlew awesomeFunJar
,生成一个类似的fat jar(21MB),运行时使用:

java -jar build/libs/myproject-standalone.jar
在这两种情况下,都包括
io.reactivex.rxjava2
依赖项

注意1:我以前没有使用过这个gradle one jar插件,而且我也没有看到定制加载程序的任何主要优势,我所看到的是,与常规胖jar相比,helloFX示例加载它所需的时间实在太长了

如果您使用它是因为fat jar没有运行,那么您可能需要一个
启动器
类,如下所述:

然后将mainClass替换为
jetliner.Launcher

注2:JavaFX插件(最新版本0.0.7)使用
实现
,它负责添加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'
}

如何启动它?我运行awesomeFunJar任务,该任务执行com.github.onslip.gradle-one-jar pluginOk中的构建函数进行构建,但当您说“当我尝试执行它时”?在IDE finder中,我右键单击构建的jar文件,然后选择run。这有点奇怪,因为您的gradle文件定义了
mainClassName='jetliner.Main'
,但是运行操作似乎愿意启动
io/reactivex/subjects/Subject
一个,也许您的启动程序配置有问题?非常感谢!使用您在注释2中提供的gradle,我成功地构建并执行了jar。唯一的一点小提示是需要保留
mainClassName='jetliner.Launcher'
,否则应用程序将无法运行
/gradlew run
是的,对,我没有粘贴它,抱歉。我会更新答案。
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'
}