JSON auslesen und Labels in GUI verwenden

learningbydoing

Aktives Mitglied
Hallo zusammen,

ich habe wieder einmal ein Problem 🙂

Ich möchte eine Json Sprachdatei auslesen und die Werte in die GUI einfügen lassen. Leider funktioniert dies nur beim "Run Projekt" innerhalb der IDE. Nach einem Clean and Build und dem ausführen der .jar, werden die Werte nicht angezeigt.

Der Code zum auslesen der JSON:

Java:
package main.java...;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.json.Json;
import javax.json.JsonObject;
import javax.json.JsonReader;


public class JsonsFileAuslesen {

    public String jsonAuslesenFunktion(String labelName, String dateiName) throws IOException {
        String label;
        String path = "jsons/" + dateiName;
        JsonObject jsonObject;
        InputStream inputStream = getClass().getClassLoader().getResourceAsStream(path);
        JsonReader jsonReader = Json.createReader(inputStream);
        jsonObject = jsonReader.readObject();
        
        
        label = jsonObject.getString(labelName);
        
        return label;
    }

    public String jsonWertAuslesen(String key, String jsonFile) {
        String wert = "";
        
        try {
            JsonsFileAuslesen keyBekommen = new JsonsFileAuslesen();
            wert = keyBekommen.jsonAuslesenFunktion(key, jsonFile);
        } catch (IOException ex) {
            // Damit etwas im Catch Block steht
        }

        return wert;
    }
}

Die JSON:

Code:
{
    "sprache": "German",
    "parameterLettering": "Parameter",
    "wordOf": "von",
    "resultLettering": "Ergebnis",
    "statusLettering": "Status",
    "cancelButton": "Abbruch",
    "saveAndQuitButton": "Report speichern und beenden",
    "checkfilenotfound": "Checksummen-Prüfdatei nicht gefunden, Programm wird beendet",
    "reportwillbesavedunder": "Der Report wird abgelegt unter"
}

Diese Schriften sollen über die JSON gezogen werden:

1663660618769.png

Woran kann das liegen? Vielleicht weil sich der Pfad in der .jar verändert hat? ...

Vielen Dank schon einmal im Voraus!
😀
 
laut deimen code sollte sich die Json Datei in einem unterOrdner unter der Jar Datei befindden was wohl nicht ist.

\...\OrdnerJarDatei\deineJar.jar
\...\OrdnerJarDatei\jsons\deineJsonDatei
 
Neben dem wichtigen Hinweis von @fhoffmann noch ein Hinweis zur Fehlersuche:

Das jar File ist auch nur ein ZIP, d.h. Du kannst es zu einem ZIP umbenennen um Dir den Inhalt anzusehen. Sind die JSON Dateien in dem Ordner jsons?

Und auch ganz wichtig: Gross- / Kleinschreibung beachten? Auf dem Dateisystem ist z.B. test.json und Test.json bei Windows gleich. Aber beim Laden aus der jar sind das zwei unterschiedliche Dateien und wenn Du test.json laden willst und es heisst Test.json, dann wird es nicht gefunden.

laut deimen code sollte sich die Jaon Datei in einem unterOrdner unter der Jar Datei befindden was wohl nicht ist.
Wie kommst Du darauf? Er greift ja über getClass().getClassLoader().getResourceAsStream(path); zu.
 
Hallo zusammen,

vielen Dank schon einmal für Eure schnellen Antworten!

Habe den Catch Block angepasst @fhoffmann.

Die Jar scheint trotzdem richtig aufgebaut und benannt zu sein (nicht wundern in main sind die Klassen):

1663666548842.png
1663666573863.png

Habe es davor mit .properties gemacht und da hat alles einwandfrei funktioniert. 🙁


Viele Grüße
 
Die Bilder zeigen den Inhalt der Jar Datei?

Hast Du die Namen kontrolliert bei den aufrufen, so dass die Schreibweise genau "de-Labels.json" "en-Labels.json" und "Fenster-Titel.json" entspricht (Also alles klein und nur "L", bzw. "F" und "T" groß)?

Bekommst Du irgend welche Fehler oder Exceptions?

Ansonsten füg noch mehr Ausgaben hinzu, so das Du testweise ausgibst, auf was Du zugreifst und was die jeweiligen Ergebnisse sind.

Du könntest auch zeigen, wie Du die Methode z.B. aufrufst. Dann könnte man das, was wir Dir sagen, dass Du es prüfen sollst, auch selbst prüfen.
 
Ja Rechtschreibung ist soweit alles richtig!
Ich rufe die Methode eigentlich ganz normal auf. Objekt erstellen und die Funktion im Objekt verwenden.

Java:
String wert = "";
JsonsFileAuslesen keyBekommen = new JsonsFileAuslesen();
wert = keyBekommen.jsonWertAuslesen("wordOf", "de-Labels.json");

Als kleines Beispiel...

Wie gesagt ich habe sonst eigentlich alles genauso gemacht wie davor bei den Properties. Da hat es ja funktioniert...
 
Also ich habe gerade nicht zu viel Zeit, das jetzt zu analysieren, aber ich habe einfach einmal schnell etwas nachgestellt:
  • Abhängigkeiten eingefügt (Ich habe jakarta.json genommen, aber das spielt keine Rolle).
  • Dann die Ressource eingebaut und einfach mal Deine Methode kopiert. Ich habe sie schnell static gemacht und dann das getClass durch Klassenname.class ersetzt:

--> getResourceAsStream lieferte bei mir immer null? Ich weiss gerade nicht, wieso der classloader da Probleme hat.

Schnelle Änderung:
a) Vor das jsons noch ein "/": String path = "/jsons/" + dateiName;
b) getClassloader() entfernen: InputStream inputStream = getClass().getResourceAsStream(path);

Nach meinem aktuellen Verständnis hätte das aber mit dem Aufruf auf dem ClassLoader selbst so funktionieren müssen. Halt mit dem Unterschied, dass es eben nicht am Ort der Klasse anfängt zu suchen sondern im Root des Classpath - daher hätte es ohne / vor dem jsons funktionieren müssen (wäre so meine Aussage - aber bei mir ging es so eben nicht).

Evtl. klappt dieser Workaround mit den beiden Schritten auch bei Dir. Erläuterung kommt evtl. später wenn ich mehr Zeit habe um mir das noch einmal im Detail anzusehen.

Edit: Evtl. vorab schon eine Vermutung: Das dürfte am Modul-System von Java 9 und höher liegen. Durch den Aufruf auf dem ClassLoader ist vermutlich die "Berechtigung" weg, darauf zu zu greifen. Dokumentation von Modul.getResourceAsStream könnte man als ersten Schritt zu Rate ziehen - da dürfte etwas mehr diesbezüglich drin stehen. Und man kann es testen - evtl. mal statt getClassloader ein getModul probieren - da dürfte es vermutlich noch weiterhin funktionieren. Aber wie gesagt: Mir fehlt die Zeit, das jetzt im Detail zu recherchieren und dann zu beschreiben.

Edit2: Evtl. auch einfach testbar durch eine Anpassung der module-info.java (so vorhanden): Entweder direkt im Kopf mit open module xxxx starten oder ein opens jsons; hinzufügen. Wenn keine module-info.java verwendet wird, dann wird es schwerer - da gäbe es dann nur die Kommandozeile, die ein add-opens ermöglichen könnte.
 
Zuletzt bearbeitet:
Also ich habe gerade nicht zu viel Zeit, das jetzt zu analysieren, aber ich habe einfach einmal schnell etwas nachgestellt:
  • Abhängigkeiten eingefügt (Ich habe jakarta.json genommen, aber das spielt keine Rolle).
  • Dann die Ressource eingebaut und einfach mal Deine Methode kopiert. Ich habe sie schnell static gemacht und dann das getClass durch Klassenname.class ersetzt:

--> getResourceAsStream lieferte bei mir immer null? Ich weiss gerade nicht, wieso der classloader da Probleme hat.

Schnelle Änderung:
a) Vor das jsons noch ein "/": String path = "/jsons/" + dateiName;
b) getClassloader() entfernen: InputStream inputStream = getClass().getResourceAsStream(path);

Nach meinem aktuellen Verständnis hätte das aber mit dem Aufruf auf dem ClassLoader selbst so funktionieren müssen. Halt mit dem Unterschied, dass es eben nicht am Ort der Klasse anfängt zu suchen sondern im Root des Classpath - daher hätte es ohne / vor dem jsons funktionieren müssen (wäre so meine Aussage - aber bei mir ging es so eben nicht).

Evtl. klappt dieser Workaround mit den beiden Schritten auch bei Dir. Erläuterung kommt evtl. später wenn ich mehr Zeit habe um mir das noch einmal im Detail anzusehen.

Edit: Evtl. vorab schon eine Vermutung: Das dürfte am Modul-System von Java 9 und höher liegen. Durch den Aufruf auf dem ClassLoader ist vermutlich die "Berechtigung" weg, darauf zu zu greifen. Dokumentation von Modul.getResourceAsStream könnte man als ersten Schritt zu Rate ziehen - da dürfte etwas mehr diesbezüglich drin stehen. Und man kann es testen - evtl. mal statt getClassloader ein getModul probieren - da dürfte es vermutlich noch weiterhin funktionieren. Aber wie gesagt: Mir fehlt die Zeit, das jetzt im Detail zu recherchieren und dann zu beschreiben.

Edit2: Evtl. auch einfach testbar durch eine Anpassung der module-info.java (so vorhanden): Entweder direkt im Kopf mit open module xxxx starten oder ein opens jsons; hinzufügen. Wenn keine module-info.java verwendet wird, dann wird es schwerer - da gäbe es dann nur die Kommandozeile, die ein add-opens ermöglichen könnte.
Vielen Dank für deine ausführliche Erklärung. Leider wird das Projekt in Java 8 entwickelt 🙁

Es bleibt bei dem eigentlichen Problem, dass alles ganz normal angezeigt wird, wenn ich das Projekt aus der IDE starte. Mache ich aber einen Clean and Build und benutze die .jar, bleibt das Programm in seinem Ladestatus hängen -> also hat wahrscheinlich keinen Zugriff auf die Jsons, bzw. kann sie nicht finden.
 
Ok, mit Java 8 hat man die beschriebene Problematik nicht.

Einfach noch einmal die bekannten Punkte durchgehen:
  • Also die Bilder in #5 sind vom jar File aufgenommen? Im jar File sind die Dateien also drin.
  • Die Schreibweise ist geprüft - Du hast also de-Labels.json auch im Code (Hast Du es mal zu Testzwecken ausgegeben?)
  • Prüfe den InputStream auf null - da wird halt keine IOException geworfen sondern eine NPE und die fängst Du ja nicht. Check und Ausgabe / Log wären sinnvoll um zu bestätigen, dass dies so nicht klappt.
  • Dürfte im Java 8 Umfeld nichts bringen, aber die beiden Punkte a und b kannst Du auch bei Java 8 mal probieren. Da erwarte ich aber keine Veränderung. (Oder entwickelst du ggf zwar mit Java 8 aber führst es mit einer höheren Java Version aus? dann könnte es wieder zu so Problemen kommen. Wie führst Du das jar aus? Evtl. mal ein java -version auf der Kommandozeile machen und auch das jar über die Kommandozeile starten mit java -jar ....)
 
Hast Du probiert, die Zeile mal anzupassen zu:
InputStream inputStream = getClass().getResourceAsStream("/jsons/" + dateiName);

Der Stream ist halt null, wenn die Ressource nicht gefunden werden konnte. Und da ist die Frage, wieso das so ist.

Aber noch einmal vom letzten Post:
Wie führst Du das jar aus? Evtl. mal ein java -version auf der Kommandozeile machen und auch das jar über die Kommandozeile starten mit java -jar ....
 
Danke nochmal für die vielen Antworten!

Ich habe es jetzt hinbekommen, indem ich zur Haupt .jar die Plugin javax-json-1.0.4.jar eingefügt habe. Damit funktioniert es jetzt.🙂 Ist nicht die schönste Form, aber immerhin funktioniert es mal👍
 

Zurück
Oben