# Ausführbare jar/exe aus JAVAFX Projekt erstellen (IntelliJ)



## DerBär (23. Jun 2019)

Guten Abend zusammen,

ich versuche aus einem JavaFX Testprojekt (Es handelt sich um ein ganz einfaches Fenster mit Button) eine ausführbare Datei zu machen.
Das Projekt lässt sich über die IntelliJ IDE ganz normal ausführen und kompilieren.

Ich habe daher versucht über IntelliJ ein Jar Archiv  was die JavaFX Abhängigkeiten und das eigentliche Prog beinhaltet zu erstellen (Siehe Screenshot für Einstellungen).
Das Jar Archiv wird auch korrekt erstellt, wenn ich es nun aber doppelklicke passiert einfach garnichts. Die Gui welche sich beim direkten Ausführen über IntelliJ öffnet startet einfach nicht.
Wenn ich die Jar datei mittels java -jar (Dateiname) über cmd aufrufe erhalte ich folgenden Hinweis:
Error: Could not find or load main class main
Caused by: java.lang.NoClassDefFoundError: javafx/application/Application

Hat da evtl. jemand eine Idee was das Problem ist?
Ich habe auch schon über die offizielle Oracle Seite versucht die Jar Datei direkt per cmd zu erzeugen, blicke da aber leider nicht so ganz durch und würde es sowieso eher lieber direkt in der IDE (IntelliJ) machen, wenn möglich.

Bin über jeden Rat dankbar!


----------



## IAmFloppy (23. Jun 2019)

Du musst kein neues Java Artifact machen, sondern bei den Artifacts JavaFX Application auswählen.


----------



## DerBär (23. Jun 2019)

IAmFloppy hat gesagt.:


> Du musst kein neues Java Artifact machen, sondern bei den Artifacts JavaFX Application auswählen.


Hey, danke für deine Antwort  .
Das hatte ich aber auch schon versucht und dann erhalte ich die Error:Java FX Packager: Can't build artifact - fx:deploy is not available in this JDK". Ich nutze JDK 12.


----------



## IAmFloppy (23. Jun 2019)

fx:deploy funktioniert seit Java 11+ nicht mehr. 
Mir fällt leider nichts ein, wie man den Fehler umgehen könnte, außer es mal mit Java 8 zu versuchen.


----------



## DerBär (23. Jun 2019)

Hmm also ich habe mir grade mal jdk 10 installiert und kann darüber auch bei den Artifacts JAVAFX Application auswählen und die Jar Datei erzeugen.
Habe damit allerdings das gleiche Problem, wenn ich die erzeugte Jar Datei starten will öffnet sich einfach keine GUI  .
Habe nochmal einen Screen von den Einstellungen angehangen, fehlt da vlt. noch was?
PS: Wenn ich die .jar über cmd mit java -jar dateiname ausführe erhalte ich nun wieder die Meldung :

Error: Could not find or load main class main
Caused by: java.lang.NoClassDefFoundError: javafx/application/Application 
Für mich sieht das fast so aus, als würde er die FX Libs irgendwie nicht finden, kann das sein?


----------



## IAmFloppy (23. Jun 2019)

Geh mal rechts auf den JavaFX Tab  Hast du da die Application Klasse drin? 
Was kommt denn jetzt wenn du es per cmd starten willst? Der gleiche Fehler?


----------



## mrBrown (23. Jun 2019)

Java 10 solltest du direkt wieder runter schmeißen, das ist nicht mehr aktuell. Nimm stattdessen Java 11 (als LTS-Version) oder 12.



Für JavaFX mit Java 11 nutzt man am besten Maven oder Gradle, damit klappt es deutlich besser, als das händisch und mit der IDE zu machen.
Eine "Uber Jar" lässt sich damit aber afaik noch nicht bauen, zumindest nicht auf einfachem Wege, da grätscht das Modul-System dazwischen (falls jemand doch einen Weg kennt, würde ich mich freuen davon zu hören  ).

Ich beschreib's mal mit Maven:
Statt Uber Jar kann man stattdessen entweder das Assembly-Plugin oder das JavaFX-Plugin mit jlink nutzen, ersteres auch ohne, letzteres nur mit Nutzung des Modul-Systems.
In beiden Fällen fällt am Ende nicht eine einzelne Datei, sondern mehrere Dateien und eine Datei zum starten bei raus, zum Verteilen kann man die dann einfach zippen. Mit Nutzung des Assembly-Plugins sind das nur das Projekt selbst inklusive eingebundener  Abhängigkeiten, im anderen Fall kommt ein ganzes JRE mit dabei raus, der Nutzer muss also nicht mal Java installiert haben.

Alle drei Varianten (ohne Modul-System, Modulsystem + Assembly-Plugin und Modulsystem+jlink) findet man kurz als Beispiel in diesem git-Repo: https://gitlab.com/mrBrown/javafx-11-demo (jeweils auf eigenen Branches)
Die Projekte sollte von jeder IDE geöffnet werden können, den Build kann man dann entweder über Kommandozeile oder über die IDE ausführen. Installiert sein müssen JDK 11 oder größer und Maven.


----------



## DerBär (23. Jun 2019)

IAmFloppy hat gesagt.:


> Geh mal rechts auf den JavaFX Tab  Hast du da die Application Klasse drin?
> Was kommt denn jetzt wenn du es per cmd starten willst? Der gleiche Fehler?



Naja ich habe als Application Klasse einfach meine main Klasse angegeben (siehe Screenshot). Hoffe mal das ist so richtig?



@mrBrown 
Vielen Dank für die ausführliche Beschreibung.
Ist mir heute etwas spät mich da noch einzulesen, werde es morgen aber direkt mal ausprobieren!


----------



## DerBär (30. Jun 2019)

So da bin ich nochmal. 
Der Einstieg in Maven war für mich als Anfänger dann doch schwieriger als gedacht und ich habe mir daher eine kleine Auszeit genommen.
Bin mittlerweile soweit, dass ich mir mit Maven eine fertige Jar Datei mit allen Dependencies die ich brauche erzeugen kann.
Mein einziges Problem ist momentan allerdings noch, dass ich diese jar nicht per Doppelklick ausführen kann, sondern immer den JavaFX12 Module Path mit java -jar --module-path C:\JavaFX_Librarys\openjfx-12.0.1_windows-x64_bin-sdk\javafx-sdk-12.0.1\lib"  mitgeben muss. So startet meine GUI zwar, wenn ich die Modul Parameter per CMD mitgebe, aber schöner wäre es natürlich, wenn das auch einfach per Doppelklick ginge. Ich habe gelesen man könne eine Modul-Info Datei definieren, brauche ich die Parameter dadurch später nicht mehr per CMD angeben? Oder gibt es einen anderen Weg die Jar so anzupassen, dass diese einfach per Doppelklick startet?


----------



## mrBrown (30. Jun 2019)

Zeig mal deine pom.xml, und nutzt du das Modul-System oder "umgehst" du das?
Deiner Beschreibung nach baust du eine fat-jar, die JavaFX enthält, nutzt dann zum starten trotzdem das installierte JavaFX-SDK - das passt nur so halb zusammen.


Per doppelklick starbare Fat-Jar geht aktuell afaik nur, wenn man das Modulsystem nicht nutzt (da ansonsten mehrere Module in einer Jar gepackt sind). Man kann das ganze aber per Skript startbar machen.


----------



## DerBär (1. Jul 2019)

Guten Abend, vielen Dank für deine Unterstützung.
Meine POM.xml sowie einen Screenshot meines "Projekts" in Eclipse habe ich mal angefügt.
PS: Mache das ganze zum Testen aktuell in Eclipse, weil ich ein gutes Tutorial gefunden hatte welches das ganze aber in Eclipse gemacht hat (Nur damit es für mich für den Anfang etwas einfacher ist).

Ich glaube was du mit der Fat Jar sagst ist korrekt, in der Jar sind die ganzen FX12 Libs enthalten und genau wie du schreibst ich verstehe eben auch nicht warum ich den Modul Pfad zu meinen lokal installierten FX Libs angeben muss, wenn diese in der Jar enthalten sind, aber ohne Angabe des Modul Pfads kann die Jar halt nicht ausgeführt werden  .



```
project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>maventest</groupId>
  <artifactId>maventest</artifactId>
  <version>1.0.0</version>
  <name>Maven Tutorial</name>
  <description>Descr. of Maven TUT</description>
  <build>
 
    <sourceDirectory>src</sourceDirectory>
    <plugins>
    <!-- COMPILE -->
     <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.0</version>
        <configuration>
          <release>12</release>
        </configuration>
      </plugin>
      <!-- ASSEMBLY JAR -->
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>3.1.0</version>
        <configuration>
            <archive>
                <manifest>
                    <mainClass>maventest.StartMavenTest</mainClass>
                </manifest>
            </archive>
            <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
            </descriptorRefs>
        </configuration>
            <executions>
                <execution>
                    <id>make-assembly</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
      </plugin>
      <plugin>
    <groupId>org.openjfx</groupId>
    <artifactId>javafx-maven-plugin</artifactId>
    <version>0.0.2</version>
    <configuration>
        <mainClass>hellofx/org.openjfx.App</mainClass>
    </configuration>
  
</plugin>
    </plugins>
  </build>
  <!--  REPOSITORIES -->
  <repositories>
  <repository>
  <id>mvnrepository.com</id>
  <url>https://mvnrepository.com/</url>
  </repository>
  </repositories>
  <!-- DEPENDENCY -->
  <dependencies>
 <!-- https://mvnrepository.com/artifact/org.openjfx/javafx -->
<dependency>
    <groupId>org.openjfx</groupId>
    <artifactId>javafx</artifactId>
    <version>12.0.1</version>
    <type>pom</type>
    <scope>compile</scope>
</dependency>

<dependency>
    <groupId>org.openjfx</groupId>
    <artifactId>javafx-controls</artifactId>
    <version>12.0.1</version>
    <scope>compile</scope>
</dependency>
 
  </dependencies>
</project>
```


----------



## mrBrown (1. Jul 2019)

Okay, das Problem ist, dass deine „Main“-Klasse Application erweitert (dann musst du das Modul-System nutzen), aber gleichzeitig eine Fat-Jar baust, mit der das Modulsystem nicht nutzbar ist.


Lösung siehe das Projekt weiter oben, im wesentlich brauchst du eine main-Methode in einer Klasse, die *nicht* von Application abgeleitet ist.


----------



## DerBär (1. Jul 2019)

Wie geil es funktioniert, dank deiner Hilfe.
Der Tipp mit der main Klasse die die eigentliche Klasse startet war genau das richtige und dank deines Github Projekts auch total einfach nachzubauen, vielen Dank.
Was du zum Modul System schreibst leuchtet mir ehrlich gesagt noch nicht so ganz ein, aber dazu werde ich mich aufjedenfall nochmal schlau machen. 
Aufjedenfall erstmal vielen Dank für die Unterstützung die erste Hürde ist schonmal genommen mir war wichtig die Programme auch auf anderen Systemen einfach ohne großen Aufwand ausführen zu können und das ist erstmal geschafft  .


----------



## mrBrown (1. Jul 2019)

DerBär hat gesagt.:


> Was hat Maven dagegen, dass meine Hauptklasse von JAVAFX.Application erbt?


Maven hat da nichts gegen (sonst würde schon das Bauen fehlschlagen), das Problem tritt erst zur Laufzeit auf, da Java afaik noch keine Multi-Module-Jars direkt unterstützt.


----------



## JudoRunner1 (12. Okt 2019)

Hi guys. Hier ist eine Lösung was IntelliJ und fx:deploy etc angeht. Es wird auch gezeigt wie mann jar ohne IntelliJ eksekutiert. Wichtig Manifest File zu korrigieren. Auch Library Setting (Project Structure) ist gezeigt. Oder wichtig ist was Extends Application angeht !!!! ;


----------

