线程“主”java.lang.NoClassDefFoundError 中的 JavaFX 异常:javafx/application/Application

Posted

技术标签:

【中文标题】线程“主”java.lang.NoClassDefFoundError 中的 JavaFX 异常:javafx/application/Application【英文标题】:JavaFX Exception in thread "main" java.lang.NoClassDefFoundError: javafx/application/Application 【发布时间】:2013-05-27 22:24:42 【问题描述】:

我收到了这个错误

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();
        
    

fxml 文件包含一个简单的 gui。

【问题讨论】:

jdk1.7's javac can't find javafx jar without -cp option 的可能重复项 我将我的类路径声明到 jfxrt.jar 的目录,我现在收到此错误:Error: Could not find or load main class 您需要将当前目录放在类路径中 => 详情请参阅:Compile JavaFX 2.0 Manually 【参考方案1】:

我正在 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 $?

【讨论】:

【参考方案2】:

在过去的几个小时里,我一直在处理同样的问题。尽管我没有看到它明确地写出来,但您似乎必须使用 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 部署。它仍然没有这个后备类。您确定 Intellij 中没有解决此问题的方法吗? 即使您安装了 Java 1.8 并且故意将 CLASSPATH 指向 javafx,您也会看到此错误消息。这发生在 DbSchema 7.6.5 中,它将类路径硬编码为排除的 javafx。我编辑了shell脚本后,这个问题就消失了。【参考方案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>

【讨论】:

【参考方案4】:

我使用 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> 

【讨论】:

【参考方案5】:

如果您像我一样使用 netbeans 并且安装了两个版本的 JDK,那么您应该在配置文件中将类路径更改为适当的 java 安装。这也是 Netbeans 中的一个错误: 有两种方法可以做到: 通过执行以下命令使用 --jdkhome 启动 NetBeans:

"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"

【讨论】:

【参考方案6】:

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

【讨论】:

【参考方案7】:

使用 java 8 应该不会出现这个问题,但它确实对我有影响

我最初是从 Eclipse Export -> Runnable Jar 创建了我的 jar,它很好。当我搬到 Maven 时,上述操作失败了。

比较这两个 jar 文件表明,jar 中没有打包任何与 fx 相关的内容(如我所料),但 Eclipse 生成的清单中有 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>

【讨论】:

【参考方案8】:

我在 javafx 中找不到 Pair 类时遇到问题。

似乎 vanilla eclipse(没有 e(fx)clipse 扩展名)不会搜索 java 附带的 javaFX 运行时 jar。

我刚刚将这个外部 jar 添加到我的 eclipse 项目构建路径中(或者如果您处于调试配置中,请在调试配置的 JRE 选项卡中添加外部 jar):

$JAVA_HOME/jre/lib/ext/jfxrt.jar

(将 JAVA_HOME 替换为您的 jdk 文件夹)

对我来说,它位于 /installs/jdk1.8.0_211/jre/lib/ext/jfxrt.jar

【讨论】:

【参考方案9】:

在eclipse环境下:将jfxrt.jar添加到MANIFEST.MF文件中的Bundle-ClassPath中。

Bundle-ClassPath: .,
jfxrt.jar

【讨论】:

更多细节。 C-【参考方案10】:

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

在运行应用程序时添加 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

【讨论】:

天哪,我已经用谷歌搜索了 2 个小时,这终于为我解决了。非常感谢!【参考方案11】:

我已经在“Ask ubntu”上回答了。 我建议您使用https://openjfx.io/openjfx-docs/。我使用的是 Eclipse IDE,但它适用于所有 IDE

那么在设置VM选项时可以参考这个全局变量为:

在IDE中右键项目->运行方式->运行配置->参数->VM参数

对于 Windows,

--module-path "\path to javafx\lib" --add-modules javafx.controls,javafx.fxml

对于 Linux,

--module-path /javafx/lib 的路径 --add-modules javafx.controls,javafx.fxml

【讨论】:

【参考方案12】:

我相信我的例子会对某人有所帮助。我没有成功构建真正可执行的 jar 文件,该文件可以通过使用 Java 8 从任何位置/目录单击来运行。迁移到 Java 11 和其他很少的业务。

    迁移到 Java 11。指定 SDK,IDE 中的其他人员,将其添加到 pom.xml

     <maven.compiler.source>11</maven.compiler.source>
     <maven.compiler.target>11</maven.compiler.target>
    

    添加 JavaFX 依赖项

     <!--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>
    

    构建应用程序

    为您的 Main 类创建包装类,它扩展了 Application

     public class Launcher 
         public static void main(String[] args) 
             Main.main(args);
         
     
    

    将以下内容添加到 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>
    

    运行这个 maven 命令

     mvn clean -Dmaven.clean.failOnError=false compile assembly:single -DskipTests=true
    

指定名称的 jar 文件将出现在目标目录中。它将独立于您运行它的位置执行。

【讨论】:

以上是关于线程“主”java.lang.NoClassDefFoundError 中的 JavaFX 异常:javafx/application/Application的主要内容,如果未能解决你的问题,请参考以下文章

主线程啥都没做,就会等待子线程结束。这是为啥?

Android 异步操作Android 线程切换 ( 判定当前线程是否是主线程 | 子线程中执行主线程方法 | 主线程中执行子线程方法 )

子线程怎么不阻塞主线程

QT中UI主窗口如何与子线程相互传递参数

java 子线程 回调 主线程

C++怎么在主线程中使用子线程的数据? 比如说主线程中有一个数组,如何在子线程中调用这个数组