Исключение JavaFX в потоке "main" java.lang.NoClassDefFoundError: javafx/application/Application

Я получаю эту ошибку

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.

Ответ 1

Я работал над этой самой проблемой в течение последних нескольких часов. Несмотря на то, что я не видел его явно, он кажется, что вы ДОЛЖНЫ использовать один из инструментов упаковки JavaFX, который является либо задачей Ant, либо исполняемым файлом javafxpackager. (См. http://docs.oracle.com/javafx/2/deployment/packaging.htm, раздел 5.3.1). В среде IDE NetBeans используется 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, приложение не будет запущено.

Чтобы проверить это, я просмотрел все четыре файла JAR в образцах JavaFX (BrickBreaker, Ensemble, FXML-LoginDemo и SwingInterop). Все они также имеют "лишние" файлы.

Для моего небольшого тестового приложения я использовал эту командную строку для создания "исполняемого" JAR файла:

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

Надеюсь, это поможет!

Ответ 2

Использование java 8 не должно давать этой проблемы, но это было для меня

Сначала я создал свою банку из Eclipse Export → Runnable Jar, и все было в порядке. Когда я переехал в Maven, это не сработало.

Сравнение двух банок показало, что ничто из fx не было упаковано с банкой (как я и ожидал), но в манифесте, создаваемом Eclipse, было Class-Path: .. Получение maven для упаковки фляги со следующими работами для меня (с 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 (который конфликтует с плагином теней) и т.д.

В решении используется 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: Это можно сделать двумя способами:
Запустите NetBeans с помощью --jdkhome, выполнив следующее:

"C:\Program Files\NetBeans Dev 201402160001\bin\netbeans.exe" --jdkhome "C:\Program Files\Java\jdk1.7.0_51"

Или установите свойство netbeans_jdkhome в файле /etc/netbeans.conf, например.

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

Ответ 6

IntelliJ и, возможно, другие IDE не реорганизуют вашу конфигурацию Run/Debug. Вы должны вручную изменить имя своего пакета, предшествующее имени вашего основного класса. Например, измените "sample.Main" на "com.company.package.ui.Main", чтобы он запускался правильно в следующий раз при попытке запустить его. IDE, возможно, уже отметила кнопку Run/Debug с красным крестом, потому что она не могла найти основной класс. Он также дает предупреждение при открытии конфигурации "Запуск/отладка".

Ответ 7

Я разрабатываю на 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 $?

Ответ 8

У меня была проблема не найти класс Pair из javafx.

Кажется, что ванильное затмение (без расширения клипа e (fx)) не выполняет поиск jar файла javaFX, включенного в java.

Я просто добавил в свой путь сборки проекта eclipse этот внешний jar файл (или, если вы находитесь в конфигурации отладки, добавьте внешний jar файл на вкладке JRE конфигурации отладки):

$ JAVA_HOME/JRE/Library/внутр/jfxrt.jar

(замените JAVA_HOME своей папкой jdk)

Для меня это было в /installs/jdk1.8.0_211/jre/lib/ext/jfxrt.jar

Ответ 9

в среде eclipse: добавьте jfxrt.jar в Bundle-ClassPath в файле MANIFEST.MF.

Bundle-ClassPath: .,
jfxrt.jar