Intellij Idea 使用gradle和intellij为JavaFX构建FatJar,获取NoClassDefFOundError

ma8fv8wu  于 2023-11-16  发布在  Java
关注(0)|答案(1)|浏览(364)

我在IntelliJ中建立了一个OpenJDK 12项目(2019.2)使用内置的Gradle支持。为了设计GUI,我使用JavaFX 12。我已经遵循并阅读了setup指南几次,我在IDE中运行程序没有问题,问题是,当我试图构建一个.jar文件进行分发时,我遇到了问题。到目前为止,我还没有找到一个有效的解决方案,我已经搜索了很多,几乎撕裂了我的头发在这一点上。目前,当我试图运行我的jar文件与java -jar“jarName”.jar我得到以下错误:

  1. Exception in thread "main" java.lang.NoClassDefFoundError: javafx/application/Application
  2. at java.base/java.lang.ClassLoader.defineClass1(Native Method)
  3. at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016)
  4. at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:151)
  5. at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:802)
  6. at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:700)
  7. at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:623)
  8. at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
  9. at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
  10. at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
  11. at com.CAM.Starter.main(Starter.java:6)
  12. Caused by: java.lang.ClassNotFoundException: javafx.application.Application
  13. at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
  14. at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
  15. at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
  16. ... 10 more

字符串
我试着把我的main类移到一个单独的类中,但这个类不能扩展Application,这就是上面的错误。如果不移动Main类,我会得到一个不同的错误。
我的build.gradle目前看起来是这样的:

  1. plugins {
  2. id 'java'
  3. id 'application'
  4. id 'org.openjfx.javafxplugin' version '0.0.8'
  5. }
  6. group 'ClassicAddonManager'
  7. version '0.2'
  8. sourceCompatibility = 11
  9. repositories {
  10. mavenCentral()
  11. }
  12. javafx {
  13. version = "12.0.2"
  14. modules = [ 'javafx.controls', 'javafx.fxml' ]
  15. }
  16. dependencies {
  17. testCompile group: 'junit', name: 'junit', version: '4.12'
  18. compile 'net.sourceforge.htmlunit:htmlunit:2.13'
  19. compile group: 'com.google.code.gson', name: 'gson', version: '2.7'
  20. compile group: 'net.lingala.zip4j', name: 'zip4j', version: '1.2.4'
  21. }
  22. jar {
  23. manifest {
  24. attributes 'Main-Class': 'com.CAM.Starter'
  25. }
  26. from {
  27. configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
  28. }
  29. }


如果我有我的main方法扩展Application,那么我会得到一个错误,说明我的main类无法找到,即使我可以看到它存在于生成的.jar文件中。
我想做的就是生成一个文件,让一个没有编程知识的朋友可以运行。理想情况下,一个他们可以运行的文件,而不必先安装Java。我知道应该可以做到这一点,但Gradle对我来说是新的,所以我不确定这是否是导致所有这些头痛的原因。有没有可能更容易的方法来部署?特别是考虑到这是一个solo项目?

编辑

我已经尝试了指南的模块化部分.这样做,我有超过100错误时,试图建立.他们都在静脉的东西:

  1. javafx.graphicsEmpty reads package org.xml.sax from both xml.apis and java.xml

fykwrbwg

fykwrbwg1#

如果你想使用Gradle而不是shadow插件来做一个fat jar,通常你会这样做:

  1. jar {
  2. manifest {
  3. attributes 'Main-Class': 'com.CAM.Starter'
  4. }
  5. from {
  6. configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
  7. }
  8. }

字符串
但是,有一个重要的事实:compile已被弃用,JavaFX插件默认使用implementation
因此,configuration.compile可能为空,或者至少不包含JavaFX类。
解决方案是检查runtimeClasspath配置,因为我们将在那里拥有所有的类,我们可以制作fat jar:

  1. jar {
  2. manifest {
  3. attributes 'Main-Class': 'com.CAM.Starter'
  4. }
  5. from {
  6. configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
  7. }
  8. }


这在OpenJFX文档中解释,https://openjfx.io/openjfx-docs/#modular,section non-modular projects,subsection gradle.
一旦你有你的脂肪罐,你可以运行它:

  1. java -jar yourFatJar.jar


请注意,双击它不会起作用,正如here中详细解释的那样,因此可以方便地创建一个小批处理。
一个更好的解决方案是做一个模块化的项目,并使用jlink创建一个运行时镜像(它还包括一个启动脚本)。你可以将这个镜像分发给其他甚至没有安装JDK的用户。使用gradle,你可以只包括'org.beryx.jlink'插件,就像这个sample一样。
您还可以使用jpackageearly version来创建和分发安装程序。

展开查看全部

相关问题