Aktuellen Pfad einer Java-Anwendung ermitteln

Wenn man mit Java eine JAR-Datei ausführt, dann wird nicht die JAR-Datei ausgeführt, sondern der Java-Bytecode dieser JAR-Datei. Der Java-Bytecode liegt aber nicht im Speicherort der JAR-Datei und somit können Referenzen wie bsp. new File("serverlog.txt"); nicht richtig gefunden werden, wenn man davon ausgegangen ist, dass in diesem Fall die Datei serverlog.txt im selben Ordner wie die ausgeführte JAR-Datei zu finden ist.

Man muss sich deshalb den zur Laufzeit gültigen Pfad der JAR-Datei holen. Für dieses Vorhaben habe ich mir eine eigene Methode geschrieben:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  /**
   * Returns the path where the currently running JAR-file is located.
   * Example value: C:\MyProject\build\jar\
   * @return Path of the JAR-file
   */
  public static String getJarExecutionDirectory()
  {
    String jarFile = null;
    String jarDirectory = null;
    int cutFileSeperator = 0;
    int cutSemicolon = -1;
 
    jarFile = System.getProperty("java.class.path");
    // Cut seperators
    cutFileSeperator = jarFile.lastIndexOf(System.getProperty("file.separator"));
    jarDirectory = jarFile.substring(0, cutFileSeperator);
    // Cut semicolons
    cutSemicolon = jarDirectory.lastIndexOf(';');
    jarDirectory = jarDirectory.substring(cutSemicolon+1, jarDirectory.length());
 
    return jarDirectory+System.getProperty("file.separator");
  }

Diese Methode liefert aber nur den richtigen Ort, wenn man die JAR Datei über die Konsole (java -jar meinprojekt.jar) ausführt. Deswegen möchte ich anhand eines Beispiels noch einen zweiten, zuverlässigeren Weg aufzeigen:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    String propertiesFilePath = "client.properties";
    File propertiesFile = new File(propertiesFilePath);
 
    if (!propertiesFile.exists())
    {
      try
      {
        CodeSource codeSource = MainView.class.getProtectionDomain().getCodeSource();
        File jarFile = new File(codeSource.getLocation().toURI().getPath());
        String jarDir = jarFile.getParentFile().getPath();
        propertiesFile = new File(jarDir + System.getProperty("file.separator") + propertiesFilePath);
      }
      catch (Exception ex)
      {
      }
    }
 
    System.out.println(propertiesFile.getAbsolutePath());

Wo liegt eigentlich root1?

Bei der Entwicklung mit der Java Platform (Micro Edition) benutzt man eine FileConnection, um die Verbindung zu einer Datei (zum lesen oder schreiben) herzustellen. Dabei wird oft der folgende Pfad verwendet:

fc = (FileConnection)Connector.open("file:///root1/");

Doch wo liegt dieser ominöse root1-Ordner? Typischerweise soll root1 das Basisverzeichnis auf dem Handy angeben. Im Java ME SDK muss man den Pfad aber mühseelig suchen. Bei mir ist es:

C:\Dokumente und Einstellungen\Benutzername\javame-sdk\3.0\work\0\appdb\filesystem\root1

Allerdings nur, wenn das ClamshellCldcPhone1 als „Platform“ in den „Properties“ des Projektes festgelegt ist. Würde man etwa das DefaultCldcPhone1 auswählen, dann würde der entsprechende Pfad zum root1-Ordner folgender sein:

C:\Dokumente und Einstellungen\Benutzername\javame-sdk\3.0\work\6\appdb\filesystem\root1\

Das liegt daran, dass jedes emulierte Handy seinen eigenen Ordner (mit entsprechender ID) hat. Die ID des Handys ist in der Titelzeile ablesbar. Der Ordner (benannt nach der ID-Nummer) liegt dann im „work“ Unter-Verzeichnis des Java Micro Edition SDK.


Emuliertes Java-Handy mit dazugehöriger Ordnerstuktur