JavaFX异常:在主线程中出现“java.lang.NoClassDefFoundError: javafx/application/Application”错误。

36

我遇到了这个错误

Exception in thread "main" java.lang.NoClassDefFoundError: javafx/application/Ap
plication
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(Unknown Source)
        at java.security.SecureClassLoader.defineClass(Unknown Source)
        at java.net.URLClassLoader.defineClass(Unknown Source)
        at java.net.URLClassLoader.access$100(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)
Caused by: java.lang.ClassNotFoundException: javafx.application.Application
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        ... 13 more

尝试运行我的类文件时,这是源代码

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

import java.util.concurrent.Executor;

public class TestApplication extends Application{

    @Override
    public void start(Stage stage) throws Exception {
        new TestApplication();
    }

    public TestApplication() {
        try{
            final Parent root = FXMLLoader.load(Executor.class.getResource("test.fxml"));
            final Stage stage = new Stage(){{
                setScene(new Scene(root, 300, 250));
                setTitle("Test");
                setResizable(false);
                show();
            }};
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

1
可能是重复的问题:jdk1.7的javac在没有-cp选项的情况下找不到javafx jar - jewelsea
我将我的类路径声明为jfxrt.jar目录,现在出现了这个错误:错误:找不到或加载主类 - Archey
1
你需要将当前目录添加到类路径中 => 详见:手动编译JavaFX 2.0 - jewelsea
12个回答

15

我在过去几个小时里一直在处理这个问题。尽管我没有明确地看到它的写法,但似乎你必须使用JavaFX打包工具之一,即Ant任务或javafxpackager可执行文件(请参见http://docs.oracle.com/javafx/2/deployment/packaging.htm的5.3.1节)。NetBeans IDE 使用 Ant 打包代码。(我正在使用 IntelliJ)

当你使用其中的一个打包方法时,除了你应用程序的所有代码和资源外,它还会将以下内容添加到你的输出JAR文件中:

/com/javafx/main/Main$1.class
/com/javafx/main/Main$2.class
/com/javafx/main/Main.class
/com/javafx/main/NoJavaFXFallback.class

有了这些就可以从命令行运行应用程序:

java -jar outjar.jar

一切正常。如果我删除额外的com.javafx.main文件,应用程序将无法运行。

为了进行双重检查,我查看了JavaFX示例中的所有四个JAR文件(BrickBreaker、Ensemble、FXML-LoginDemo和SwingInterop)。它们都有“额外”的文件。

对于我的小型测试应用程序,我使用以下命令行构建了一个“可执行”JAR文件:

javafxpackager -createjar -appclass sample.Main -outfile outjar -v -nocss2bin -srcdir C:\workspaces\garoup1\out\production\javafx1

希望这能帮到您!


我正在使用Intellij并遇到了这个问题。但是我看到它使用ant进行构建和javafxpacker进行部署。然而,它仍然没有这个fallback类。你确定在Intellij内部没有解决方法吗? - Gadelkareem
即使您已安装Java 1.8并且已将CLASSPATH指向JavaFX,您仍会看到此错误消息。这发生在DbSchema 7.6.5中,其中硬编码了排除JavaFX的类路径。编辑了shell脚本后,此问题消失了。 - Kemin Zhou

7

我相信我的例子能帮到某些人。之前我没有成功地构建出真正可执行的jar文件,不能通过单击从任何位置/目录运行,并且需要安装Java 8。但是转移到了Java 11并进行了一些其他调整,问题得到了解决。

  1. Move to Java 11. Specify SDK, other staff in IDE, add this to pom.xml

     <maven.compiler.source>11</maven.compiler.source>
     <maven.compiler.target>11</maven.compiler.target>
    
  2. Add JavaFX dependencies

     <!--JavaFX-->
     <dependency>
         <groupId>org.openjfx</groupId>
         <artifactId>javafx</artifactId>
         <version>15.0.1</version>
         <type>pom</type>
     </dependency>
     <!--JavaFX-controls-->
     <dependency>
         <groupId>org.openjfx</groupId>
         <artifactId>javafx-controls</artifactId>
         <version>15.0.1</version>
     </dependency>
    
  3. Build application

  4. Create wrapper class for your Main class, which extends Application

     public class Launcher {
         public static void main(String[] args) {
             Main.main(args);
         }
     }
    
  5. Add the following to pom.xml

     <build>
     <resources>
         <resource>
             <directory>src/main/resources</directory>
         </resource>
     </resources>
     <plugins>
         <plugin>
             <groupId>org.apache.maven.plugins</groupId>
             <artifactId>maven-jar-plugin</artifactId>
             <version>3.2.0</version>
             <configuration>
                 <archive>
                     <manifest>
                         <addClasspath>true</addClasspath>
                         <mainClass>path-to-launcher.Launcher</mainClass>
                     </manifest>
                     <manifestEntries>
                         <Class-Path>.</Class-Path>
                     </manifestEntries>
                 </archive>
             </configuration>
         </plugin>
         <plugin>
             <groupId>org.apache.maven.plugins</groupId>
             <artifactId>maven-assembly-plugin</artifactId>
             <version>3.3.0</version>
             <configuration>
                 <finalName>final-jar-file-name</finalName>
                 <archive>
                     <manifest>
                         <mainClass>path-to-launcher.Launcher</mainClass>
                     </manifest>
                 </archive>
                 <descriptorRefs>
                     <descriptorRef>jar-with-dependencies</descriptorRef>
                 </descriptorRefs>
                 <appendAssemblyId>false</appendAssemblyId>
             </configuration>
             <executions>
                 <execution>
                     <id>make-assembly</id>
                     <phase>package</phase>
                     <goals>
                         <goal>single</goal>
                     </goals>
                 </execution>
             </executions>
         </plugin>
     </plugins>
     </build>
    
  6. Run this maven command

     mvn clean -Dmaven.clean.failOnError=false compile assembly:single -DskipTests=true
    
指定名称的JAR文件将出现在目标目录中。它将可执行,无论您从何处运行它。

在我的情况下,我只需要使用JDK 11进行编译,并且了解到我的问题是javafx.util.Pair,只需添加javafx-controls重新部署依赖项即可解决问题。 - Dagon

7

我遇到了同样的问题,以下步骤帮助我解决了它:

在运行应用程序时添加vm参数,

--module-path  /home/user/Java-libraries/openjfx-11.0.2_linux-x64_bin-sdk/javafx-sdk-11.0.2/lib/ --add-modules javafx.controls,javafx.fxml

注意:

  • --module-path 将包含 Java fx 的 jars。
  • 我使用的是 open-jdk 13。

如果您正在使用 Eclipse,请在其中进行配置,或者您可以像以下这样进行编译和运行:

编译

javac --module-path /path/to/java-fx-libs/ --add-modules javafx.controls,javafx.fxml *.java

运行

java --module-path /path/to/java-fx-libs/ --add-modules javafx.controls,javafx.fxml MyMainClass

4
使用java 8不应该出现这个问题,但是对于我来说确实出现了。
我最初是通过Eclipse导出 -> 可执行Jar来创建我的jar包,当我转移到Maven时,它失败了并出现了上述错误。
对比两个jar包,发现没有fx相关内容被打包进去(正如我所期望的),但是Eclipse生成的清单(manifest)中有Class-Path: .。使用以下命令让maven将jar包打包成功(使用Java 8)。
 <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <configuration>
          <archive>
            <manifest>
              <addClasspath>true</addClasspath>
              <mainClass>com.pg.fxapplication.Main</mainClass>
            </manifest>
              <manifestEntries>
                    <Class-Path>.</Class-Path>
                </manifestEntries>
          </archive>
        </configuration>
      </plugin>
    </plugins>
  </build>

3

我知道这可能不是启动javafx应用程序的“正确”方法,但我已经为此问题苦苦挣扎了一段时间,并想出了一个解决方法,它不需要使用任何外部打包应用程序,也不需要强制使用ant或maven插件(与shade插件冲突)等......

解决方案使用Utils4j在运行时动态加载jfxrt。你不能在扩展javafx.application.Application的类中加载它,在一个单独的类中执行此操作并将其命名为:Launcher

import org.fuin.utils4j.Utils4J

public class Launcher {

    public static void main(String[] args) {
        Utils4J.addToClasspath("file:///"+System.getProperty("java.home")+ File.separator+"lib"+File.separator+"jfxrt.jar");

// CODE TO RUN YOUR CLASS THAT EXTENDS javafx.application.Application goes here.

    }
}

你可以将Utils4j与你的项目一起使用(如果使用maven):
    <dependency>
        <groupId>org.fuin</groupId>
        <artifactId>utils4j</artifactId>
        <version>0.7.0</version>
    </dependency>

1

我使用maven,只需在终端中运行以下命令mvn install:install-file -Dfile="/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/jfxrt.jar" -DgroupId=com.oracle.javafx -DartifactId=javafx -Dversion=2.2 -Dpackaging=jar(Windows可能会有些许不同)。然后maven将安装jfxrt.jar,之后您可以简单地引用它。

<dependency>
  <groupId>com.oracle.javafx</groupId>
  <artifactId>javafx</artifactId>
  <version>2.2</version>
</dependency> 

1
我已经在“Ask Ubuntu”上回答过了。我建议您使用https://openjfx.io/openjfx-docs/。我正在使用Eclipse IDE,但它适用于所有IDE。
然后,当设置VM选项时,您可以引用此全局变量,如下所示:
在IDE中右键单击项目->Run As->Run Configuration->Arguments->VM Arguments
对于Windows,
--module-path "\path to javafx\lib" --add-modules javafx.controls,javafx.fxml
对于Linux,
--module-path /path to javafx/lib --add-modules javafx.controls,javafx.fxml

1
如果您像我一样使用NetBeans,并且安装了两个JDK版本,则应该在配置文件中将类路径更改为适当的Java安装。这也是NetBeans中的一个错误: 有两种方法可以解决这个问题:
第一种方式是通过执行以下内容启动NetBeans --jdkhome:
"C:\Program Files\NetBeans Dev 201402160001\bin\netbeans.exe" --jdkhome "C:\Program Files\Java\jdk1.7.0_51"

或者在 /etc/netbeans.conf 文件中设置 "netbeans_jdkhome" 属性,例如:

# Default location of JDK, can be overridden by using --jdkhome <dir>:
netbeans_jdkhome="C:\Program Files\Java\jdk1.7.0_51"

1

IntelliJ和其他IDE可能不会重构您的运行/调试配置。您必须手动更改主类名前的包名称。例如,将“sample.Main”更改为“com.company.package.ui.Main”,以便在下次尝试运行时正确启动。IDE可能已经用红叉标记了运行/调试按钮,因为它找不到主类。打开运行/调试配置时还会发出警告。


0

我正在Linux上开发一个简单的WebApp,我遇到了同样的错误,但很容易解决它(假设你像我一样在命令行上开发)。

cat compile.sh 
 #!/bin/bash

 /usr/lib/jvm/jdk1.7.0_25/bin/javac WebViewSample.java  -cp /usr/lib/jvm/jdk1.7.0_25     
 /jre/lib/jfxrt.jar

 $ cat run.sh 
 #!/bin/sh
 JAVA_HOME=/usr/lib/jvm/jdk1.7.0_25/bin/
 CLASSPATH=/usr/lib/jvm/jre1.7.0_25/lib/jfxrt.jar:. 

 $JAVA_HOME/java -cp $CLASSPATH WebViewSample $* 2>&1 /dev/null | awk -F\| '{ print  $2"|"$3  ; exit $1 }'

 exit $?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接