Jar-File Start nur über Terminal

WIng2005

Mitglied
Hallo zusammen,

ich habe eine Server-App zur Steuerung von Arduino geschrieben und bisher erfolgreich auf einem Win10-Rechner laufen. Nun habe ich das Ganze auf Linux Mint portiert und stehe vor einem Rätsel:
Die App liest eine Ziel-IP aus einer ini-Datei.
Java:
            Properties props = new Properties();
            FileInputStream in = new FileInputStream("./setup.ini");
            props.load(in);
            in.close();
            String str = props.getProperty("db_ip");

Die ini-Datei liegt im gleichen Verzeichnis. Prinzipiell funktioniert das auch, allerdings nur, wenn ich das JAR-File über das Terminal (java -jar file.jar) starte. Versuche ich das Ganze per Doppelklick im Dateimanager, liest er die ini-Datei nicht aus (File-not-Found-Exception). Hab ich hier einen Denkfehler, oder warum ist das Verhalten unterschiedlich? Ich bin in der Session, wie auch im Terminal als normaler Benutzer unterwegs, nicht als root.

Danke für jeden Tipp..

VG
Steffen
 
Hi,
ich hatte zuvor die Angabe nur über ("setup.ini"), was auch nicht ging (aus der IntelliJ und auf dem bisherigen Win-Rechner läuft es). Herauszufinden ist, was der Unterschied zwischen dem Aufruf per Terminal und dem Aufruf per Gui/Doppelklick ist. Beide starten das eigentliche Java-Programm... nur der Zugriff auf die Datei scheint unterschiedlich geregelt.

VG
Steffen
 
Also das werden jetzt etwas mehr Punkte...

a) Das eigentliche Problem: Ich meine, dass das Arbeitsverzeichnis immer das System32 Verzeichnis war oder so und nicht das Verzeichnis, in der die JAR Datei ist. Daher kann auf die Datei per ./setup.ini nicht zugegriffen werden.

b) Wenn man Probleme bekommt, dann gibt die Details aus! Also fang Exceptions und gebe diese aus. Dabei ist es egal, ob Du ein Logfile in ein temporäres Verzeichnis schreibst oder ob Du dann ein Dialogfenster öffnest. Wichtig ist, dass Du an die Details heran kommen musst.

c) Generell sollte man auch nicht in Exceptions laufen sondern Dinge vorab prüfen. So kannst Du per Klasse File prüfen, ob es eine Datei "./setup.ini" gibt. Wenn es die nicht gibt, dann kannst Du davon auch den absoluten Pfad mit ausgeben - dann weisst Du auch genau, wo er danach gesucht hat. Das hilft dann auch enorm.

d) Wenn Du den Pfad der JAR Datei brauchst, dann kannst Du den ermitteln. Dazu kannst Du eine Klasse aus der JAR Datei verwenden:
ClassOutOfJar.class.getProtectionDomain().getCodeSource().getLocation().getPath()

Das ist aber eine Methode, die fehl schlagen kann, wenn gewisse Tools verwendet werden, die den Bytecode verbergen sollen (Das Tool jar2exe hat sowas z.B. gemacht).

e) Es ist eine ganz schlechte Idee, Java Programme nur als JAR weiter geben zu wollen. Das ist eine alte Idee, die lange überholt ist. Und noch zu Zeiten, wo Sun und später Oracle an dieser Idee festgehalten haben, gab es dann Massen an Tools um eben diese Problematik zu lösen. launch4j, jar2exe, .... Viele freie und kommerzielle Software Produkte gab es. Und alle hatten gemein, dass man eine Runtime mitgeben konnte. Das ist aber obsolet, da es nun andere Wege gibt wie JPackage oder die Verwendung von GraalVM / NativeImage.

Ja, es bläht ein Paket auf, wenn man eine Runtime mitgibt, aber hier über MB zu meckern wo wir im TB Bereich sind und wir selbst in Deutschland schnelle Internetverbindungen haben, ist aus meiner Sicht falsch. Und wenn es so wichtig ist: Dann ist Java ggf. einfach das falsche Mittel.

f) Und da es um eine setup.ini geht - Baust Du einen Installer selbst? Das ist aus meiner Sicht auch explizit der falsche Weg. Statt dessen sollte man auf die jeweiligen Mittel der Plattform zurückgreifen. Bei Windows ist das ganz klar die Bereitstellung eines MSI, Macs bekommen in der Regel einfach die App in einem DMG aber es kann auch ein pkg kommen und Linux - ja da hat man Kraut und Rüben: deb, rpm, ... Aber selbst da wird man dann vermutlich ein Format wählen, das Distributions-übergreifend ist oder man gibt einfach ein tgz zum entpacken....

Das wären so die Punkte, die mir hier gerade so durch den Kopf gehen würden ...
 
Das hat sich jetzt überschnitten....


Ich habe mir mal den aktuellen Pfad ausgeben lassen.

Java:
String filepath=System.getProperty(user.dir);

Ergebnis:
Terminal: tatsächlicher Ort des JAR- und somit auch des INI-Files -> /Home/User/Schreibtisch/Ordner
Per Gui und Doppelklick: Das User-Root /Home/User

Am liebsten wäre mir ein einfaches öffnen per relativem Pfad, aber es schein, als läuft die Ermittlung des aktuellen Verzeichnisses als Bezugspunkt schon falsch.

VG
Steffen
 
Also das werden jetzt etwas mehr Punkte...

a) Das eigentliche Problem: Ich meine, dass das Arbeitsverzeichnis immer das System32 Verzeichnis war oder so und nicht das Verzeichnis, in der die JAR Datei ist. Daher kann auf die Datei per ./setup.ini nicht zugegriffen werden.

b) Wenn man Probleme bekommt, dann gibt die Details aus! Also fang Exceptions und gebe diese aus. Dabei ist es egal, ob Du ein Logfile in ein temporäres Verzeichnis schreibst oder ob Du dann ein Dialogfenster öffnest. Wichtig ist, dass Du an die Details heran kommen musst.

c) Generell sollte man auch nicht in Exceptions laufen sondern Dinge vorab prüfen. So kannst Du per Klasse File prüfen, ob es eine Datei "./setup.ini" gibt. Wenn es die nicht gibt, dann kannst Du davon auch den absoluten Pfad mit ausgeben - dann weisst Du auch genau, wo er danach gesucht hat. Das hilft dann auch enorm.

d) Wenn Du den Pfad der JAR Datei brauchst, dann kannst Du den ermitteln. Dazu kannst Du eine Klasse aus der JAR Datei verwenden:
ClassOutOfJar.class.getProtectionDomain().getCodeSource().getLocation().getPath()

Das ist aber eine Methode, die fehl schlagen kann, wenn gewisse Tools verwendet werden, die den Bytecode verbergen sollen (Das Tool jar2exe hat sowas z.B. gemacht).

e) Es ist eine ganz schlechte Idee, Java Programme nur als JAR weiter geben zu wollen. Das ist eine alte Idee, die lange überholt ist. Und noch zu Zeiten, wo Sun und später Oracle an dieser Idee festgehalten haben, gab es dann Massen an Tools um eben diese Problematik zu lösen. launch4j, jar2exe, .... Viele freie und kommerzielle Software Produkte gab es. Und alle hatten gemein, dass man eine Runtime mitgeben konnte. Das ist aber obsolet, da es nun andere Wege gibt wie JPackage oder die Verwendung von GraalVM / NativeImage.

Ja, es bläht ein Paket auf, wenn man eine Runtime mitgibt, aber hier über MB zu meckern wo wir im TB Bereich sind und wir selbst in Deutschland schnelle Internetverbindungen haben, ist aus meiner Sicht falsch. Und wenn es so wichtig ist: Dann ist Java ggf. einfach das falsche Mittel.

f) Und da es um eine setup.ini geht - Baust Du einen Installer selbst? Das ist aus meiner Sicht auch explizit der falsche Weg. Statt dessen sollte man auf die jeweiligen Mittel der Plattform zurückgreifen. Bei Windows ist das ganz klar die Bereitstellung eines MSI, Macs bekommen in der Regel einfach die App in einem DMG aber es kann auch ein pkg kommen und Linux - ja da hat man Kraut und Rüben: deb, rpm, ... Aber selbst da wird man dann vermutlich ein Format wählen, das Distributions-übergreifend ist oder man gibt einfach ein tgz zum entpacken....

Das wären so die Punkte, die mir hier gerade so durch den Kopf gehen würden ...
Hi und danke für die Antwort. Mal zur Erklärung: das Programm ist exakt 1x im Umlauf...und das bei mir auf dem Server. Manuelles Übertragen des JAR- und INI-Files sind hier nicht das Problem. Das ganze läuft unter Linux (Mint 21).
Fehler bei der Ermittlung der DB-IP wir in einem Try-Catch Block abgefangen und der Fehler ausgegeben : File-not-Found-Exception.
Mich wundert nur, dass 2 Wege, die gleiche Datei zu starten, zu unterschiedlichen Ergebnissen führen.

VG
Steffen
 
Also bist Du nicht unter Windows sondern auf einem Mac unterwegs 🙂
Hast Ja Linux MInt geschrieben ... das /Home hatte mich irritiert. Der große Anfangsbuchstabe war irritierend .. Bei Macs ist es /Users/ und nicht /home ...

Und da geht es ja um das Arbeitsverzeichnis - und das ist - je nachdem, wie Du etwas startest, immer anders. Beim Terminal gibst Du es ja vor aber das kann da dann auch jedes Verzeichnis sein.

Bei so Dateien ist immer die Frage: Wer ändert die denn wann? Wenn der User das ändern können soll, dann ist es üblich, sowas im Home Verzeichnis zu plazieren. Also z.B. als .myapp.ini oder so. (myapp dann natürlich der Name Deiner App). Da hast Du dann Zugriff drauf.
Der Zugriff erfolgt dann über die Property user.home.

Das behebt dann so Probleme komplett. Denn auch auf dem Terminal kann das Arbeitsverzeichnis ja woanders sein...

Edit: Hatte zwischen Fenstern umschalten müssen und dann hatte er beim zurück wechseln irgendwie den Fokus falsch und hat es vorzeitig abgesendet.
 
Hi Konrad,
entwickeln tue ich auf meinem MAC, der erste Server war Windows. Weil dieses aber permanent updatet und neustartet (geht leider nicht zu deaktivieren), habe ich auf einen Linux-Mint portiert. Dort liegt die App und die ini aktuell auf dem Schreibtisch in einem Ordner. Via Terminal starte ich also das gleiche, was ich per Klick in der Gui starte. Trotzdem gibt mit System.getProperty(user.dir) einmal den Ordner auf dem Schreibtisch und einmal den UserRoot aus. Das verstehe ich nicht.
Es schein also, als wenn java -jar filename das ganze ins aktuelle Verzeichnis übersetzt, der Doppelklick als executable es zwischenparkt...

VG
Steffen
 
Zuletzt bearbeitet:
Der Unterschied kommt ja einfach von der Art und Weise, wie etwas gestartet wird. Wenn Du im Terminal bist, dann hast Du da ein definiertes Arbeitsverzeichnis. Bei dem Doppelklick hast Du das aber erst einmal nicht. Durch den Doppelklick wird ja von dem Desktop Environment die Auswertung gemacht und dann kommt ein Aufruf. Und der Aufruf sieht dann etwas vor a.la. "java -jar vollerPfadMitJarDatei" - nur eben wird das vom Desktop Environment ausgeführt und das hat dann irgend ein Arbeitsverzeichnis. Man kann hier diskutieren, ob es Sinn machen würde, dass dies das Verzeichnis der Datei ist, aber das ist bei vielen Umgebungen meines Wissens nach nicht so.

Was Ich hier machen würde (Du willst ja nichts weitergeben sondern nur selbst nutzen): Pack alles an einen Ort, den Du gut findest (z.B. ~/bin/myapp/ - das ist so das Pattern, das ich auf Unix Systemen nutze), in ~/bin habe ich dann in der Regel ein Shell-Script, das den Start macht. Dann kann ich sowas auf der Kommandozeile starten. Und in der Desktop Umgebung erstelle ich einfach ein Shortcut. Damit landet es dann in den Menüs oder man kann es auf dem Desktop plazieren und so ....

Das wäre ein möglicher Ansatz ohne dann an der Anwendung selbst etwas ändern zu müssen. Die anderen Wege sind natürlich alle auch super und aus meiner Sicht bessere Wege, aber wenn Du alleine alles nutzen willst, dann dürfte es schlicht Overkill sein. Daher die Idee dieses Workarounds.
 
Hi Konrad,
ich fürchte hier bin ich nicht wissend genug zu... wenngleich ich via google schon einiges rausgefunden habe:
Mein Tool liegt jetzt unter/opt/tool. Das shellscript liegt unter /usr/local/bin (soweit aus dem Ubuntu-Forum unter OPT gefunden):
Java:
#!/bin/sh
cd /opt/tool/
    java .jar file.jar

Wie bekomme ich das jetzt als Starter aufs Desktop?

VG
Steffen
 
Also erst einmal muss es -jar und nicht .jar sein ... aber das wird wohl ein Fehler sein bei der Übertragung ins Forum sein, denn Du hast das ja bestimmt getestet.

Welchen Desktop verwendest Du denn? Evtl. reicht es, einen Softlink auf das Script in Desktop zu erstellen.

Teilweise werden .desktop Dateien verwendet für z.B. Menu Einträge und so. Die können auch auf dem Desktop plaziert werden. Das sind Text-Dateien mit einem Inhalt wie:
Code:
[Desktop Entry]
Type=Application
Name=MeineApp
Exec=/pfad/zur/ausfuehrbarenDatei
Icon=/pfad/zum/icon.png
Categories=Utility;
 
Hallo Konrad,

was soll ich sagen..... geht... perfekt! Vielen Dank für deine Unterstützung.

Was ich jetzt habe (und korrigiert mich, falls die Pfade singfrei sind-> alles ergoogelt und auf Basis von Halbwissen)

Die Anwendung liegt jetzt im Ordner: /opt/Tool/file

Im Ordner /usr/local/bin/ liegt ein Script:

Java:
#!/bin/sh
cd /opt/tool/
java -jar file.jar

Ausführbar gemacht (chmod +x)

Dann Starter.desktop wie oben beschrieben...... läuft.

VG
Steffen
 

Neue Themen


Zurück
Oben