# Name der ausführenden jar-Datei abfragen



## Sasa (1. Okt 2005)

Hallo,

wenn ich mein Programm in eine ausführbare jar-Datei packe, würde ich zur *Laufzeit* gerne wissen, wie der Name dieser Datei ist. Ich möchte den Wert nicht in den Code schreiben, schließlich kann der Benutzer den Namen ja geändert haben.

Mit welchem Java-Befehl geht das?


----------



## Sasa (3. Okt 2005)

Hab' den Befehl gefunden:

```
System.getProperty("java.class.path");
```


----------



## Roar (3. Okt 2005)

Sasa hat gesagt.:
			
		

> Hab' den Befehl gefunden:
> 
> ```
> System.getProperty("java.class.path");
> ```


nä nich wirklich... das liefert dir den ganzen classpath, und kann ne ganze menge sein...
nen befehl der dir das zurückgibt gibts nicht, was willst du damit machen?


----------



## Sasa (3. Okt 2005)

Okay, hast recht. Die Methode gibt den ganzen Classpath zurück, allerdings besteht der bei meinem Programm zum Glück nur aus dem Dateinamen der jar-Datei. Deshalb funktioniert das, was ich vorhatte bis jetzt ganz gut.

```
String executingPath = System.getProperty("java.class.path");
if (executingPath.endsWith(".jar")) {
  try {
    JarFile jarFile = new JarFile(executingPath);
    Enumeration enumeration = jarFile.entries();
    while (enumeration.hasMoreElements()) {
      JarEntry entry = (JarEntry) enumeration.nextElement();
      String entryName = entry.getName();
      if (entryName.endsWith(".properties")) {
        System.out.println(entryName);
      }
    }
  } catch (IOException e) {
    System.err.println(e);
    e.printStackTrace();
  }
}
```
Damit lese ich aus, welche properties-Dateien verfügbar sind. Wenn der Benutzer noch was anderes als Classpath angibt, habe ich ein Problem?! :bahnhof:


----------



## Bleiglanz (3. Okt 2005)

prinzipiell verständlich, aber:

wenn du das ganze eh als jar verteilst, dann weisst du doch beim Erstellen des jars schon welche properties-Dateien da drin sind? 
Dann könnte man ja gleich mit ant eine "Meta"-Property Datei basteln die alle diese Namen enthält?

ausserdem nicht besonders robust: du gehst davon aus, dass dein jar immer als letztes im Classpath steht...


----------



## Sasa (3. Okt 2005)

Um mal zu testen, was System.getProperty("java.class.path") so alles zurückgeben kann, habe ich versucht den Wert für Classpath zu ändern, aber im Programm blieb er immer gleich. Daher die (dumme ) Frage: Wie ändere ich den Classpath? (Mit "-classpath <path>" passiert irgendwie nichts)

@Bleiglanz: An eine Meta Properties-Datei habe ich auch schon gedacht, doch wieso ant?

Ich gehe davon aus, dass die Benutzer meines Programms intelligent, gemein und faul sind. Das heißt ich traue ihnen zu, dass sie die jar-Datei ändern, also properties-Dateien löschen oder hinzufügen aber nicht die Meta-Datei ändern (wollen), sondern vom Programm erwarten, dass es die Änderung erkennt.


----------



## Roar (3. Okt 2005)

Sasa hat gesagt.:
			
		

> @Bleiglanz: An eine Meta Properties-Datei habe ich auch schon gedacht, doch wieso ant?


öhm, damit du das nich bei jedem jar build von hand machen musst?



> Ich gehe davon aus, dass die Benutzer meines Programms intelligent, gemein und faul sind. Das heißt ich traue ihnen zu, dass sie die jar-Datei ändern, also properties-Dateien löschen oder hinzufügen aber nicht die Meta-Datei ändern (wollen), sondern vom Programm erwarten, dass es die Änderung erkennt.


pf, wenn der benutzer an programmdateien rumfummelt braucht er sicht nicht zu wundern wenn das programm nich mehr richtig funktioniert.


----------



## Bleiglanz (3. Okt 2005)

> Ich gehe davon aus, dass die Benutzer meines Programms intelligent, gemein und faul sind


dann musst du es wohl oder übel dynamisch erkennen...

in dem Fall ist es aber doch blöd, wenn du die überhaupt ins jar packst, lass sie einfach im Dateisystem liegen (im gleichen Ordner wie die jar)??


----------



## 0xdeadbeef (3. Okt 2005)

Die Kernfrage bleibt, warum der Name der Jar-Datei bekannt sein muß. Um Ressourcen aus dem Jar zu laden, muß dessen Name nicht bekannt sein, sondern lediglich der Name der Ressource.
Ist es tatsächlich so, daß Dein Programm nicht weiß, welche Properties-Dateien es laden könnte/müßte?

Abgesehen davon gibt es außer dem Classpath noch eine zweite/bessere Methode um an den Namen des Jars zu kommen und zwar über den ClassLoader.

Ich hatte hier mal was dazu gepostet, wenn auch in einem anderen Kontext:
http://www.java-forum.org/de/viewtopic.php?p=127962&highlight=#127962



```
String iniFileStr ;
       String s = this.getClass().getName().replace('.','/') + ".class";
       URL url = this.getClass().getClassLoader().getResource(s);
       int pos;
       try {
           iniFileStr = URLDecoder.decode(url.getPath(),"UTF-8");
       } catch (UnsupportedEncodingException ex) {};
```

Im String iniFileStr befindet sich jetzt der gesamte Pfad+Filename der aufrufenden Klasse.
Falls die Klasse in einem Jar liegt, beginnt der String mit "file:". Danach folgt der Name
des Jars, dann der der Klasse. Mußt man halt noch auseinanderpflücken...


----------



## Sasa (3. Okt 2005)

Danke 0xdeadbeef! :toll: Damit habe ich auf alle Fälle schon mal eine Variante, die zuverlässig funktioniert.

Allerdings habe ich auch den Classpath noch nicht ganz abgeschrieben, wäre irgendwie einfacher. Ich habe mein Programm mit: "java -jar -classpath <beliebigerPfad> meinProgramm.jar" aufgerufen. Und System.getProperty("java.class.path") liefert sinngemäß immer noch die Ausgabe "meinProgramm.jar". Außerdem habe ich die Umgebungsvariable CLASSPATH manipuliert und es hatte keine Auswirkungen.



			
				Roar hat gesagt.:
			
		

> öhm, damit du das nich bei jedem jar build von hand machen musst?


Ach so, also nur um das ganze zu automatisieren. :roll:


----------



## 0xdeadbeef (3. Okt 2005)

Meine bisherige Erfahrung zeigt auch, daß der Classpath dem Namen des Jar-Files entspricht, wenn man den Classpath aus einem Jar heraus abfragt, und daß es sich nicht von "außen" beeinflussen läßt.
Ich bin mir aber halt nicht sicher, ob das eine zugesicherte Eigenschaft ist. Es wäre auch denkbar, daß dieses spezielle Verhalten nur bei bestimmten Versionen der JVM oder gar nur auf bestimmten Betriebssystemen auftritt.


----------



## Sasa (6. Okt 2005)

Um nun den eigentlichen Dateinamen aus der URL zu erhalten, habe ich folgenden Code geschrieben:

```
String jarFileName = null;
String s = this.getClass().getName().replace('.','/') + ".class";
URL url = this.getClass().getClassLoader().getResource(s);
String path = null;
try {
  path = URLDecoder.decode(url.getPath(),"UTF-8");
} catch (UnsupportedEncodingException e) {
  System.err.println(e);
  e.printStackTrace();
}
if (path != null && path.startsWith("file:")) {
  if (path.lastIndexOf(":/") > 4) { // Falls das Laufwerk "file" heißt
    int end = path.lastIndexOf(".jar!");
    int begin = path.lastIndexOf("/", end) + 1;
    jarFileName = path.substring(begin, end);
  }
}
```

Ich wüsste gerne, ob das eine vernünftige und zuverlässige Lösung ist.


----------

