# Netbeans zu IntelliJ mit Maven konvertieren



## MiMa (22. Dez 2022)

Nach der Trennung von JavaFX aus dem JDK laufen meine Projekte mehr schlecht als recht unter Netbeans und das gefummel  möchte ich mir nich länger antun. Daher habe ich mich entschieden meine Java und JavaFX Projektdateien von Netbeans zu IntelliJ konvertieren.

Damit die Handhabung der Anhängigkeiten von Bibliotheken auch etwas eleganter ist, möchte ich in Zukunft von Maven das erledigen lassen.
Nun habe ich mal ein Netbeans JavaFX Projekt mit IntelliJ geöffnet.
Es wurde Ant Dateien erkannt und konvertiert.
Durch Add Framework habe ich dann Maven hinzugefügt und die entsprechende Java 13 Version als auch JavaFX 13 hinzugefügt.

Die POM sieht wie folgt aus.

```
<?xml version="1.0" encoding="UTF-8"?>
<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>groupId</groupId>
    <artifactId>DMS</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>13</maven.compiler.source>
        <maven.compiler.target>13</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-graphics</artifactId>
            <version>13</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>13</version>
        </dependency>
    </dependencies>

</project>
```

Ja ich weis, das diese nicht vollständig ist, aber ich wollte mal das Programm Starten und sehen ob es funktioniert.
Beim Build Projekt kamen keine Fehlermeldungen.
Allerdings bekam ich eine Meldung das Java FX runtime Komponenten fehlten, die benötigt werden?!?!
JavaFX ist doch eingebunden und in den Depedencies enthalten?

Bei diesen Umstrukturierungen habe ich mir auch überlegt, ob es sinnvoll wäre von IntelliJ ein JavaFX Maven Projekt zu erzeugen und dann die ganzen Quellcodes herüber zu kopieren?


----------



## KonradN (22. Dez 2022)

Das Problem kann einfach sein, dass zwar alles da ist, aber der Classloader lädt die Startklasse auf eine Art und Weise, dass dann leider die Runtime nicht gefunden wird so die Startklasse von Application erbt.

Wenn Du also eine Startpunkt hast wie:

```
package de.kneitzel;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class JavaFXApp extends Application {

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Hello World!");
        Button btn = new Button();
        btn.setText("Say 'Hello World'");
        btn.setOnAction(e -> System.out.println("Hello World!"));

        StackPane root = new StackPane();
        root.getChildren().add(btn);
        primaryStage.setScene(new Scene(root, 300, 250));
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
      
}
```

(Man sieht also das extends Application!)

Dann fügt man eine weitere Startklasse hinzu:

```
package de.kneitzel;

/**
 * Another Main class as workaround when the JavaFX Application ist started without
 * taking care os Classloader Requirements of JavaFX. (Important when starting from inside NetBeans!)
 */
public class Main {
    /**
     * Additional main methode to start Application.
     * @param args Commandline Arguments.
     */
    public static void main(String[] args) {
        JavaFXApp.main(args);
    }
}
```

Wenn man diese zweite Klasse als Startklasse nimmt, dann sollte die JavaFX Applikation starten. (So das Projekt ansonsten sauber ist. Das kann ich natürlich nicht sehen. Wenn da noch irgendwelche ant Scripte erkannt und genutzt wurden von IntelliJ, dann fehlen ggf. die Abhängigkeiten, da eben nicht das Maven Projekt herangezogen wurde.

(Die Beispiele habe ich aus https://github.com/kneitzel/JavaFXMavenApp entnommen - das könnte auch ein Startpunkt sein für Deine Projekte und Du hättest dann auch so Dinge wie statische Codeanalyse und das bauen von Images mit drin.)


----------



## MiMa (22. Dez 2022)

Die main Methode habe ich ebenfalls in der gleichen Klasse und im Grunde lief das ganze mal.
Mir ist auch in anderen Projekte die ich mal mit IntelliJ geöffnet habe aufgefallen, das zwar eine main Methode enthalten war aber eine Fehlermeldung von IntelliJ kam, das keine main vorhanden sei?

Auch habe ich mal das Problem das bei compile die Meldung kommt "invalid target realeade: 13"

Wäre es besser mit IntelliJ ein JavaFX Projekt mit Maven Unterstützung zu erstellen und dann den Quellcode in dieses Projekt hinein zu kopieren?
Ich habe das Gefühl, dass das IntelliJ Projekt das aus einem Netbeans Projekt erstellt wurde eventuell an vielen Ecken und Kanten diese Probleme erzeugen könnten?

Habe mir deineJavaFXApp geladen und gesehen was du meinst.


----------



## KonradN (22. Dez 2022)

MiMa hat gesagt.:


> Wäre es besser mit IntelliJ ein JavaFX Projekt mit Maven Unterstützung zu erstellen und dann den Quellcode in dieses Projekt hinein zu kopieren?
> Ich habe das Gefühl, dass das IntelliJ Projekt das aus einem Netbeans Projekt erstellt wurde eventuell an vielen Ecken und Kanten diese Probleme erzeugen könnten?


Ja, das klingt etwas danach.

Generell würde ich dabei dann auch auf aktuelle Versionen wechseln. Also Java 17 (LTS Version) oder 19 (aktuelle Version) und so.

Bei so Migrationen gehe ich immer hin und erstelle das Maven Projekt von Grund auf neu. Da lasse ich nichts übernehmen oder generieren. Gerade in Maven ist es so, dass Vieles durch Konventionen festgelegt ist. So man sich an diese hält ist es dann möglich, viele Konfigurationen bei Bedarf zu kopieren. Mie den migrierten Projekten stimmen die Verzeichnisse meist schon nicht. So wird NetBeans die Sourcen auch einfach in src liegen haben. Bei Grade werden diese in src/main/java erwartet. Eine Datei, die aber unter src liegt, wird nicht als Java Klasse erkannt und damit gibt es die Klasse (und mit ihr die main Methode) schlicht nicht aus Sicht von IntelliJ. (Das ist jetzt nur eine Vermutung, aber das könnte der Grund für Deine Probleme sein).


----------



## MiMa (22. Dez 2022)

Ja wenn ich mal vergleiche wie die Maven Projekte strukturiert sind ist mir gleich aufgefallen, das bei meinen Netbeans Projekten die URL fehlt wie
de.MiMa.projektname.
Erst als ich deine Videos gesehen und im Blog gelesen habe das dies eine festgelegte Struktur ist, konnte ich mir vorstellen das es etwas damit zu tun haben könnte.
Mein Problem ist das ich unmengen von Netbeans von Projekte habe die aktuell nicht mehr zu überreden sind in Netbeans zu laufen, kann ich auch nicht wirklich feststellen, welches die letzten Versionen sind. Daher wollte ich in IntelliJ schnell mal eine Projekt öffnen und Starten bevor ich entscheide ob es weg kann.


----------



## MiMa (23. Dez 2022)

Das Ausführliche Video ist sehr aufschlussreich und verständlich. Danke dafür.
Bei meinem ersten Versuch ein Netbeans Projekt zu konvertieren habe ich ein paar Kompilierungs Fehlermeldungen.

```
[ERROR] /D:/Programmierung/IntelliJ/DMS/src/main/java/de/mima/dms/modelle/EinstellungenMOD.java:[12,27] package org.apache.logging.log4j is not visible
  (package org.apache.logging.log4j is declared in the unnamed module, but module de.mima.dms does not read it)
```

Ich habe dann IntelliJ geöffnet und das Projekt dann mit IntelliJ geöffnet.
Allerdings wurde nicht erkannt, das es sich um ein Maven Projekt handelt.
Ich habe dann Maven Toolkit hinzu gefügt was auch gelang aber die pom.xml war nicht die die ich im Hauptverzeichnis erstellt hatte?

Muss ich bei IntelliJ ein JavaFX Maven Projekt erstellen und dann die Quellcodedateien einfügen?


----------



## KonradN (23. Dez 2022)

MiMa hat gesagt.:


> package org.apache.logging.log4j is declared in the unnamed module, but module de.mima.dms does not read it


Du hast eine Abhängigkeit, die keine module-info hat. Und du hast eine module-info.java (was auch notwendig ist, wenn Du mit JLink arbeiten willst).

Meine Empfehlung hier:
a) Nimm ein sauberes Maven Projekt. Das kannst Du per IntelliJ erzeugen oder Du nimmst das JavaFX Projekt von mir von GitHub. Beides geht. Letzteres ist etwas einfacher, wenn Du so Abhängigkeiten haben solltest und ein Image zur Weitergabe erstellen möchtest. Aber wenn Du es nicht nimmst, dann bauen wir das moditect Plugin später von Hand ein.
b) dann den Code aus dem bestehenden Projekt kopieren. Die java Dateien, die Du vermutlich in src findest, landen in src/main/java. Alle Dateien, die keine Endung auf .java haben, landen in src/main/resources. Die Ordnerstruktur behältst Du bei (Also die Ordnerstruktur, die bei java die Namespaces bilden und so).
c) bei Abhängigkeiten schaust Du, was da die letzten Versionen sind und nutzt diese. Bei log4j ist das Problem, dass sich da von 1.x zu 2.x einiges geändert hat - da kannst Du also nur die letzte Unter-Version der Hauptversion nutzen (also sollte es 1.x sein, dann wäre das die letzte 1.2.x). Ich hoffe, dass da dann schon module-info dabei sind. Der aktive Part, der nur zur Laufzeit dazu genommen wird, ist aber ohne module-info und da muss man etwas basteln. Dazu gab es hier einen anderen Thread und im anderen Repository gibt es einen Branch, der das löst. (Und das Video dazu steht immer noch aus...)


----------



## MiMa (23. Dez 2022)

Ich habe in IntelliJ ein neues Projekt erzeugt als JavaFX v19 mit GIT und Maven.
Habe dann die pom.xml mit Log4j2 v2.19  aktualisiert, die module-info kontrolliert und korrigiert.
Durch die Änderung der Verzeichnisstruktur haben sich die Package Informationen in den Klassen geändert, mussten angepasst werden und im Quellcode mussten ebenfalls ein paar Klassenaufrufe korrigiert werden.
Ist schon ganz schön Arbeit, das hätte ich jetzt nicht gedacht. Daher habe auch nur das nötigste implementiert um das Programm starten zu können. Mit IntelliJ ist es wirklich sehr einfach Fehler zu finden und zu beseitigen.

Bei dem Programm handelt es sich um das Grundgerüst meiner Applikation und wird Schritt für Schritt erweitert.
Aktuell sind keine Fehler enthalten, zumindest werden keine angezeigt. Die Applikation startet und läuft aber es wird kein Oberfläche angezeigt.
Ich vermute das es irgendwo ein Problem mit dem FXML Loader aufgetreten ist und eventuell die fxml entweder nicht finden kann oder der Pfad falsch ist.
Ich habe es in einem anderen Maven Projekt auch auf diese weise gemacht und es funktionierte, allerding mit JavaFX 17??
Jedoch habe ich gelernt, das die FXML und CSS keine Java Dateien sind und in das Verzeichnis "ressources" gehören.
Der FXML Loader sieht so aus

```
public void hauptFenster() {
        LOG.info("Programmstart - Hauptfenster wird geladen hauptFenster()-Methode");
        try {
            FXMLLoader ladeFXML = new FXMLLoader(DMSstart.class.getResource("/fenster/Hauptfenster.fxml"));
            BorderPane fensterLayout = ladeFXML.load();
            Scene hauptInhalt = new Scene(fensterLayout);

            hauptFenster.setTitle("DMS");
            hauptFenster.setScene(hauptInhalt);
            hauptFenster.show();
        } catch (IOException e) {
            LOG.error("Es ist ein Fehler beim laden des Hauptfensters aufgetreten");
        }
    } // hauptFenster
```

Und die FXML Datei ist wie folgt abgelegt.

```
.../IntelliJ/DMS/src/main/resources/fenster/Hauptfenster.fxml
.../IntelliJ/DMS/src/main/resources/fenster/hauptfenster.css
```

Im Logfile konnte ich die Meldung sehen das beim laden des Hauptfensters ein Fehler aufgetreten ist.
Ist der FXML Loader in Java 19 verändert worden?


----------



## KonradN (23. Dez 2022)

Ändere bitte den Log Aufruf in dem catch:
`LOG.error("Es ist ein Fehler beim laden des Hauptfensters aufgetreten", e);`

Diese Log Methoden haben alle eine Variante, die auch eine Exception mitnimmt. Dann erscheinen auch die Exception Details. Es ist halt eine Exception aufgetreten, aber noch wissen wir nicht, was genau passiert ist.

So auf dem ersten Blick sieht es gut aus - Die Dateien liegen an der richtigen Stelle (Im Text hast Du einen Tippfehler - "ressources" - das wird nicht mit doppeltem s geschrieben. Aber in dem Code-Fenster hast Du den Pfad ja kopiert und da ist es korrekt.


----------



## MiMa (23. Dez 2022)

Danke, jetzt gibt es mehr Infos über die Fehlerquelle


```
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2707) ~[javafx-fxml-19-win.jar:?]
    at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:933) ~[javafx-fxml-19-win.jar:?]
    at javafx.fxml.FXMLLoader$InstanceDeclarationElement.processAttribute(FXMLLoader.java:981) ~[javafx-fxml-19-win.jar:?]
    at javafx.fxml.FXMLLoader$Element.processStartElement(FXMLLoader.java:230) ~[javafx-fxml-19-win.jar:?]
    at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:755) ~[javafx-fxml-19-win.jar:?]
    at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2808) ~[javafx-fxml-19-win.jar:?]
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2634) ~[javafx-fxml-19-win.jar:?]
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2548) ~[javafx-fxml-19-win.jar:?]
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2516) ~[javafx-fxml-19-win.jar:?]
    at de.mima.dms.start.DMSstart.hauptFenster(DMSstart.java:40) ~[classes/:?]
    at de.mima.dms.start.DMSstart.start(DMSstart.java:87) ~[classes/:?]
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:847) ~[javafx-graphics-19-win.jar:?]
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:484) ~[javafx-graphics-19-win.jar:?]
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:457) ~[javafx-graphics-19-win.jar:?]
    at java.security.AccessController.doPrivileged(AccessController.java:399) ~[?:?]
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:456) ~[javafx-graphics-19-win.jar:?]
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96) ~[javafx-graphics-19-win.jar:?]
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method) ~[javafx-graphics-19-win.jar:?]
    at com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184) ~[javafx-graphics-19-win.jar:?]
    at java.lang.Thread.run(Thread.java:1589) ~[?:?]
Caused by: java.lang.ClassNotFoundException: Kontroller.HauptfensterKON
    at jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) ~[?:?]
    at jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) ~[?:?]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:521) ~[?:?]
    at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:931) ~[javafx-fxml-19-win.jar:?]
```


----------



## KonradN (23. Dez 2022)

In der fxml Datei hast Du einen Kontroller angeben und der scheint nicht zu existieren. Hast Du den ggf. umbenannt / verschoben?

`Caused by: java.lang.ClassNotFoundException: Kontroller.HauptfensterKON`

Also da den Eintrag `controller="Kontroller.HauptfensterKON"` anpassen. Wenn Du die fxml Datei in IntelliJ öffnest, dann sollte (bei der Code-Ansicht) der Part auch rot unterstrichen sein und beim Anpassen sollte IntelliJ die mit Intellisense helfen.


----------



## MiMa (23. Dez 2022)

Oh ja, die Verzeichnisstruktur hatte sich ja geändert. Hab es korrigiert, richtig hoffe ich? 

```
fx:controller="de.mima.dms.kontroller.HauptfensterKON"
```

Demnach erhalte ich weitere Fehlermeldungen sieht ähnlich aus wie oben, habe jedoch
das herausgezogen, was direkt hervor sticht.


```
...
javafx.fxml.LoadException:
/D:/Programmierung/IntelliJ/DMS/target/classes/fenster/Hauptfenster.fxml:81
...
...
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field private javafx.scene.control.ListView
de.mima.dms.kontroller.HauptfensterKON.listviewDateiListe accessible: module de.mima.dms.start
does not "opens de.mima.dms.kontroller" to module javafx.fxml
```

Probleme mit dem ListView? sieht aus als wenn in der FXML etwas nicht stimmt?
Ich öffne das mal mit dem Scene Builder in IntelliJ und schaue mal alle Container nach?!?
Dürfte außer dem Controller Pfad nichts drin sein was der neuen Struktur stören dürfte.


----------



## KonradN (23. Dez 2022)

Ja, der FXMLLoader arbeitet mit Reflection und das geht beim Modulsystem nur, wenn man das auch erlaubt.

In der module-info.java entweder noch mittels opens den Namespace freigeben:
`opens de.mima.dms.kontroller;`
(Das kann man auch noch einschränken, dass man es nur für javafx.fxml öffnen, aber wozu?)

Oder man öffnet generell einfach alles. Dazu wäre dann einfach am Anfang zu schreiben:
`open module de.mima.dms.start {`
(Sprich: das open davor setzen.)


----------



## MiMa (23. Dez 2022)

Habe den ganzen Tag damit Verbracht das zum laufen zu bringen und nach vielen probieren scheint es jetzt Hauptfenster jetzt zu funktionieren.
Das Hauptfenster und auch das Einstellungen geht jetzt. 
Bin ich froh 
Vielen Dank für die Unterstützung

Ich wünsche schöne Festtage


----------



## KonradN (23. Dez 2022)

Das opens nimmt den package Namen und nicht den Modulnamen. Du musst also das Package angeben.

Und die Fehlermeldung deutet darauf hin, dass du eine Action angegeben hast, die es so nicht gibt im Controller.
Die Methode buttonEinstellungenVariable gibt es im Controller nicht.


----------

