System-Property "user.dir"

Guten Morgen,

hoffe mal, dass ich mit meiner Frage hier richtig bin …
Leider stehe ich gerade ein wenig auf dem Schlauch :frowning:

Wir haben vor einigen Tagen die neue Java-Version V1.8.0_101 installiert (JRE und JDK).
Leider musste ich gestern nun feststellen, das „user.dir“ (also das Arbeitsverzeichnis) jetzt plötzlich auf den Pfad des installierten JREs zeigt und nicht mehr auf den bei uns notwendigen Ordner „user.home/desktop/nnn“ !

Dieser Desktop-Ordner ‚nnn‘ ist der spezielle Ordner, in dem alle notwendigen Dateien für die Anwendung liegen und aus dem heraus die Anwendung gestartet wird. Dies ist u. a. notwendig, da beim Programmstart eine ganze Reihe Dateien von WebServer herunter geladen und lokal in diesem Ordner (rsp. div. Unterordnern) gespeichert werden.

Durch den falschen Pfad werden alle diese Unterordner und Dateien nun im Pfad des installierten JREs gespeichert.

Ein händisches Setzen mittels System.setProperty(„user.dir“,„user.home/desktop/nnn“) scheitert nun zunächst daran, dass diese Ordner auf den einzelnen Clientrechnern nicht zwingend überall gleich benannt sind.

Wie kann ich beim Start einer Anwendung den absoluten Pfad des jeweiligen Ordners, in dem gestartet wird, abfragen, um die Eigenschaft dann neu zu setzen ??

Danke im voraus!
Gruß Klaus

Klingt seltsam. Ich habe jetzt extra 1.8u101 (MacOS) installiert um zu überprüfen ob es bei mir auch so ist, mit diesem Code

        System.out.println(System.getProperty("user.dir"));```

Als Ausgabe erhalte ich:


1.8.0_101
/Users/<hier könnte ihr name stehen>/NetBeansProjects/SO



Ich habe das jeweils mit NetBeans 8.1 und Eclipse Mars (4.5.0) getestet


Edit:
Wenn deine Experimente erfolgreich sind, kannst du ja Bescheid sagen ;)

Moin,

das ist alles mehr als seltsam …
Ich habe vorhin die Methode “File.getCanonicalPath()” gefunden und mal als allerersten Aufruf eingebaut:

File directory = new File( "." );
try
{
    String sWorkingDir = directory.getCanonicalPath();
    System.err.println( "Current directory's canonical path: " + sWorkingDir );
    System.setProperty( "user.dir", sWorkingDir );
}
catch( IOException e )
{
    // TODO Auto-generated catch block
    e.printStackTrace();
}

Wenn ich jetzt die Anwendung aus Eclipse aus aufrufe, sehe ich den entsprechend korrekten Pfad.
Wenn ich die Anwendung auf den WebServer lade und von dort downloade, klappt es bei mir NICHT mehr, bei einem Kollegen mit identischen System (hier übrigens Win7) schon !

Verstehen tue ich es nicht … :wizard:

Gruß Klaus

Also wenn “Du -> Bauen -> hochladen” funktioniert nicht,
Wenn “Er -> Bauen -> hochladen” funktioniert?

Nein, er hat die Sourcen nicht … er lädt ‘nur’ runter und führt aus …

EDIT/BTW: mit “getAbsolutePfad” genau das Gleiche … :sick:
ICh möchte nicht mehr Besitzer dieser Sourcen sein :grr:

*** Edit ***

  • div. Versuche, den Pfad händisch beim Programmstart zu setzen, klappten bei mir nur beim Aufruf aus Eclipse, NICHT jedoch aus dem entspreechenden Desktop-Ordner heraus (bei einem Kollegen spannenderweise jedoch schon)
  • nach dem ich bei mir das JDK (!!) auf V1.8.0_74 zurückgesetzt und damit compiliert habe, lief es auch hier bei mir problemlos
  • es ist also wohl nicht das aktuelle JRE, sondern das aktuelle JDK das Problem … müssen wir dann wohl erstmal mit leben

[quote=vfl_freak;136979]Wenn ich jetzt die Anwendung aus Eclipse aus aufrufe, sehe ich den entsprechend korrekten Pfad.
Wenn ich die Anwendung auf den WebServer lade und von dort downloade, klappt es bei mir NICHT mehr[/quote]
was heißt denn ‘downloade’, doch nur wieder denselben Quelltext/ kompilierte Datei, und der dann auf die gleiche Weise bei dir in Eclipse ausgeführt bringt Fehler?
das wäre ja wunderlich

der Rest klingt bisher allein danach, dass fraglich ist wie der Webserver (oder was auch immer) den Code ausführt, wie jener gestartet wird,
im Code selber kannst du dazu nicht viel beeinflussen,
das hängt vom Betriebssysteem des WebServers, den Pfaden dort und der genauen Art des Aufrufes ab,

was da falsch liegen kann weiß ich zwar nicht, aber von dir vielleicht zu untersuchen/ noch genauer zu beschreiben?

funktioniert noch System.getProperty(“user.home”)?
ist es von dort festgelegter Pfad oder immer noch variabel?

notfalls Konfiguarationsdatei mit genauer Ablage das Verzeichnisses, was sich langfristig zur Sicherheit vielleicht eh anbietet,

edit: es gibt auch noch die Wege über ClassLoader, relativ zur .class-Datei, bei Jar wie auch immer
Xy.class.getResource(".").toURI() usw., wäre das ein sicheres Verzeichnis, vor dort aus zurückzurechnen?

Moinsen,

[quote=SlaterB]was heißt denn ‚downloade‘, doch nur wieder denselben Quelltext/ kompilierte Datei, und der dann auf die gleiche Weise bei dir in Eclipse ausgeführt bringt Fehler?
das wäre ja wunderlich[/quote]
Also was ich meinte, war: Code ändern und (a) direkt in Eclipse ausführen oder (b) compilieren, auf denm WebServer laden und dann von dort per WebStart aufrufen!

Schon klar … ‚WebServer‘ ist hier so ein Thema ( … immer noch Win2K … !!) :suspect:
Aber dort hatte sich ja nun gar nicht geändert!
Nur mein lokales JRE und das verwendete JDK!

was heißt: von dort festgelegt??? Hat die Variable, die von ‚Java‘ festgelegt/ausgegeben wird …
Und JA, jetzt mit dem neuen Update 101/102 funktioniert das wieder! Da gab es beim Upadate 91/92 Probleme …
https://bugs.openjdk.java.net/browse/JDK-8154899

Wir haben zwar Konfig-Dateien, aber auch sie werden beim Programmstart von WebServer geladen, damit unser Chef dort immer Änderungen an Pfaden/Zeiteinstellungen etc. fürs Programm vornehmen kann und dies auf alle Clients (ca. 60 - 80 Stück) quasi automatisch verteilt/aktualisiert wird …

Nun ja, es scheint, wie gesagt wohl am JDK101 zu hängen und nicht an der JRE101 …

Gruß Klaus

ich meinte, wäre von user.home aus der Pfad zu bestimmen, immer ‚desktop/nnn‘ anhängen

evtl. übersehen vielleicht auch noch meinen edit beachten, Xy.class.getResource(„.“).toURI() wird wohl nicht kaputt sein, auch eine Variante,
aber einen solcher Bug, wie nun klar ist, kann auch wirklich besser abgewartet werden, falls möglich, statt aufwendig durch Umbau zu umgehen

Moin,

wie eingangs geschrieben:

Ok, Dein EDIT hatte ich in der Tat überlesen :wink:
Müsste ich mal ausprobieren, aber wir werden jetzt erstmal weiter mit dem JDK 1.8.0_74 leben …

Danke und Gruß
Klaus

[quote=vfl_freak;136975]Leider musste ich gestern nun feststellen, das “user.dir” (also das Arbeitsverzeichnis) jetzt plötzlich auf den Pfad des installierten JREs zeigt und nicht mehr auf den bei uns notwendigen Ordner “user.home/desktop/nnn” ![/quote]Meine vermutung ist, dass da mit eurem Installer was durcheinander gekommen ist, so dass der den “Arbeitspfad” am Starter-Icon nicht mehr auf “user.home” setzt.

Aber wenn ihr sowoeso “user.home” wollt, warum nehmt ihr dann nicht das passende Property?
https://docs.oracle.com/javase/8/docs/api/java/lang/System.html#getProperties--

bye
TT

na ist doch schon alles recht geklärt,
es gibt den Java-Bug “JDK-8154899 - System property ‘user.dir’ now set to ‘java.home’ value rather than user’s working directory [nur Web Start anscheinend]” (!) wie gepostet,

es wird nichts verändert außer dem JDK, reproduzierbar Fehler oder nicht je nach Version

und user.home hatte ich ja auch schon angefragt, “user.home/desktop/nnn” war nur ein Beispiel, das genaue steht anscheinend nur in “user.dir”,
oder evtl. noch Class.getResource() usw.

Moin,

na, der ‚Installer‘ ist die ganz normale jre-8u101-windows-i586.exe (rsp. auch 102) …
Was genau meinst Du jetzt mit Starter-Icon? Die entstehende Verknüpfung??

Nochmal:
‚user.home‘ klappt ja jetzt wieder: „C:\Users\username“
‚user.dir‘ (das Arbeitsverzeichnis) klappt ja nicht und steht statt auf „C:\Users\username\Desktop\MeinOrdner“ auf „C:\Program Files (x86)\Java\jre1.8.0_102“
Somit werden alle Dateien, die bei Programmstart im völlig falschen Pfad gespeichert …
Siehe eben: Loading... für die Vorgänger-Version 91/92

Gruß Klaus

klappte immer, aber ist nicht ausreichend, weil Pfad dahinter noch variabel weitergeht?
oder wurde dieses Property auch mal auch falsch gemappt?

nee, sorry - bin das mit den Namen durcheinander gekommen (zumal ich hier nebenbei noch zwei andere Probleme zu lösen versuche) …
Der Kollege hatte eben mit den Start auch schon wieder Probleme, aber IMHO andere …
Hab’ für heute die Nase gestrichen voll - und mache erst mal Feierabend, um den Kopf frei zu bekommen :sick:

Hmm, konnte mich noch nie mit user.dir anfreunden - gab immer wieder zu merkwürdige Ergebnisse.
Du hast WebStart erwähnt - dürfte ja grundsätzlich schon mal einen Unterschied machen da der WebStart-cache ja meist ganz wo anders liegt. Da du aber auch gemeint hast das die Anwendung unter anderem auch in <user.home>/Desktop/X liegt und dies variable ist klingt es eher nach ner “normalen” Desktop-Applikation. Da würde folgender “Klassiker” (der ja immer wieder kritisiert wird - dazu nach dem Code mehr) vermutlich weiterhelfen:

File ME=new File(this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI());
//...```
Warum wird dieser Code (unter anderem von euch) immer wieder kritisiert: Weil er für System-Klassen die vom bootstrap-classloader geladen wurden NULL liefert. Ich kann nur immer wieder drauf antworten: is' doch mal völlig Wurscht - es geht um >**THIS**<.getClass() - nicht um java.lang.X - und dafür funktioniert es auch. Voraussetzung ist halt nur dass es sich beim laufenden Code um normalen lokal gestarteten Code handeln muss - wie das bei WebStart ist kann ich nicht sagen da ich mangels CodeSign-cert mich damit nicht befasse (und auf der endlosen Suche im Netz bisher noch keinen Anbieter gefunden habe der java codesign-certs kostenfrei ausstellt (warum eigentlich? für https kommts doch auch langsam in schwung)).
In ME steht dann der Pfad zum aktuellen .jar in dem die Klasse liegt in der diese Zeile läuft (mit Java 7 kann man das sogar noch statisch machen dass man nicht mal mehr ein Objekt braucht - ist aber viel native reflection krams) - und davon ausgehend holt man sich mit File.getParentFile() ein File-Objekt auf den Ordner in dem dieses .jar liegt - fertig ende aus.

Man kann auch noch Krücken versuchen wie `Thread.currentThread().getContextClassLoader().getResource(Thread.currentThread().getStackTrace()[0].getClassName().replace(".", "/")+".class")` - aber dass dürfte noch um einiges Fehleranfälliger sein als der andere Einzeiler.

Sonst noch absoluter overkill: Class<?> clazz=java.lang.invoke.MethodHandles.lookup().lookupClass(); - ist aber quasi auch nur ein "statisches" this.getClass() - für das man dann auch gleich direkt ClassName.class schreiben kann.

[quote=vfl_freak;137018]‘user.dir’ (das Arbeitsverzeichnis) klappt ja nicht und steht statt auf “C:\Users\username\Desktop\MeinOrdner” auf “C:\Program Files (x86)\Java\jre1.8.0_102”
Somit werden alle Dateien, die bei Programmstart im völlig falschen Pfad gespeichert[/quote]“user.dir” ist immer der Pfad, aus dem die Anwendung gestartet wird. Mann kann sich nie darauf verlassen, dass das irgend ein besimmter Platz auf der Festplatte ist.

Wer das tut ist selber Schuld…

bye
TT

[QUOTE=Timothy_Truckle;137083]“user.dir” ist immer der Pfad, aus dem die Anwendung gestartet wird. Mann kann sich nie darauf verlassen, dass das irgend ein besimmter Platz auf der Festplatte ist.

Wer das tut ist selber Schuld…

bye
TT[/QUOTE]

Naja ist ja nicht so als würden nicht auch “größere” Programme sich darauf verlassen, dass sie in ihrem Verzeichnis gestartet werden.

naja, eben nicht !!
Das war bis V8_77 so (in unserem Fall halt „C:\Users\username\Desktop\MeinOrdner“), derzeit ist es eben generell der Java-JRE-Ordner !!
Wird wohl erst ab V9 behoben (siehe Link oben) !!

Gruß Klaus

EDIT: und das war jetzt auch mindestens seit 9 Jahren so … so lange, wie ich hier in der Firma bin :cool: