java.lang.NoClassDefFoundError: io/reactivex/subjects/Subject when building jar in Intellij Idea (gradle + JavaFX 11)
java.lang.NoClassDefFoundError: io/reactivex/subjects/Subject when building jar in Intellij Idea (gradle + JavaFX 11)
我正在 运行使用 JavaFX 11 (OpenFX) 安装一些应用程序。该应用程序是用 IntellijIdea 编写并使用 gradle 构建的。当 运行ning 在 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'
}
为了构建 jar,我 运行 awesomeFunJar 任务。
您在构建中遇到的主要问题与您如何使用 implementation
(不再是 compile
)定义依赖关系有关,而另一方面,您基于 configurations.compile
.
由于 implementation
和 compile
不同,configurations.compile
仅包含项目的 classes,不包含第三方依赖项(包括 JavaFX)。
运行构建任务将生成一个非常小的 3 KB 的 fat jar。显然这个 jar 缺少依赖项中的所有 classes。
解决方案
将您的 jar 任务 configurations.compile
替换为 configurations.compileClasspath
:
jar {
from { configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) } }
manifest {
attributes 'Main-Class': 'jetliner.Main'
}
}
运行 ./gradlew build
生成一个 fat jar(大约 23 MB,具有给定的依赖项),可以是 运行 和:
java -jar build/libs/myproject.jar
或 运行 ./gradlew awesomeFunJar
生成类似的 fat jar (21 MB),运行s 具有:
java -jar build/libs/myproject-standalone.jar
在这两种情况下,io.reactivex.rxjava2
依赖项都包含在内。
注意 1:我以前没有使用过这个 gradle-one-jar 插件,而且我没有看到自定义加载器有什么主要优势,我所看到的是,与普通的 fat jar 相比,helloFX 样本的加载时间真的太长了。
如果你使用它是因为 fat jar 没有 运行,也许你需要 Launcher
class,如 :
所述
public class Launcher {
public static void main(String[] args) {
Main.main(args);
}
}
然后用jetliner.Launcher
替换mainClass。
注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'
}
我正在 运行使用 JavaFX 11 (OpenFX) 安装一些应用程序。该应用程序是用 IntellijIdea 编写并使用 gradle 构建的。当 运行ning 在 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'
}
为了构建 jar,我 运行 awesomeFunJar 任务。
您在构建中遇到的主要问题与您如何使用 implementation
(不再是 compile
)定义依赖关系有关,而另一方面,您基于 configurations.compile
.
由于 implementation
和 compile
不同,configurations.compile
仅包含项目的 classes,不包含第三方依赖项(包括 JavaFX)。
运行构建任务将生成一个非常小的 3 KB 的 fat jar。显然这个 jar 缺少依赖项中的所有 classes。
解决方案
将您的 jar 任务 configurations.compile
替换为 configurations.compileClasspath
:
jar {
from { configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) } }
manifest {
attributes 'Main-Class': 'jetliner.Main'
}
}
运行 ./gradlew build
生成一个 fat jar(大约 23 MB,具有给定的依赖项),可以是 运行 和:
java -jar build/libs/myproject.jar
或 运行 ./gradlew awesomeFunJar
生成类似的 fat jar (21 MB),运行s 具有:
java -jar build/libs/myproject-standalone.jar
在这两种情况下,io.reactivex.rxjava2
依赖项都包含在内。
注意 1:我以前没有使用过这个 gradle-one-jar 插件,而且我没有看到自定义加载器有什么主要优势,我所看到的是,与普通的 fat jar 相比,helloFX 样本的加载时间真的太长了。
如果你使用它是因为 fat jar 没有 运行,也许你需要 Launcher
class,如
public class Launcher {
public static void main(String[] args) {
Main.main(args);
}
}
然后用jetliner.Launcher
替换mainClass。
注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'
}