# Ordner im Archiv (jar) auslesen



## jonius (20. Feb 2011)

Ich habe ein Jar-Archiv, aus dem das Programm gestartet wird. Was ich suche, ist eine Möglichkeit, zur Laufzeit einen Ordner im Archiv nach Dateien zu durchsuchen. Also per Quelltext mir alle Dateien in einem Ordner innerhalb des Archivs auflisten zu lassen. So wie es mit new File("xyz").list() in einem normalen Ordner möglich ist.


----------



## Antoras (20. Feb 2011)

Dafür gibt es die Klasse 
	
	
	
	





```
java.util.jar.JarFile
```
:

```
String jarName() {
  final String s[] = this.getClass.getProtectionDomain().getCodeSource().getLocation().toString().split("/");
  return s[s.length - 1];
}

// Zugriff auf das Archiv
new JarFile(jarName()).entries();

// Iteration über die Dateien im Archiv
for (final JarEntry e : Collections.list(new JarFile(jarName()).entries())) {
  ...
}
```


----------



## jonius (20. Feb 2011)

Danke, das werde ich mir mal ansehen. Danach habe ich gesucht.


----------



## jonius (14. Mrz 2011)

Jetzt habe ich es endlich einmal ausprobiert, allerdings funktioniert es bei mir nicht. Abgesehen davon, dass du bei getClass die Klammern vergessen hast, liefert bei mir die Methode jarName() den String "rsrc:."
Das Programm befindet sich in einem ausführbaren Jar-Archiv. Hast du eine Idee, woran das liegt?


----------



## Antoras (14. Mrz 2011)

Hm, was gibt denn 
	
	
	
	





```
this.getClass.getProtectionDomain().getCodeSource().getLocation()
```
 aus?

Das sollte eigentlich die Form 
	
	
	
	





```
file:/path/to/program.jar
```
 haben.


----------



## jonius (14. Mrz 2011)

Da bekommt ich "rsrc:./". Ich habe es sowohl unter Linux, als auch unter Windows ausprobiert. Ich hatte in Erinnerung das früher auch schon so in etwa gemacht zu haben, aber irgendwie klappt es nicht. Ich schaffe es nicht, mir den Pfad zur Jar, bzw. einfach den Namen während der Laufzeit zu ermitteln.


----------



## Antoras (14. Mrz 2011)

Von dem Fehler hab ich noch nie was gehört. Bist du sicher, dass das JAR nicht kaputt ist? Wie erstellst du das Archiv?


----------



## jonius (14. Mrz 2011)

Ich habe das Archiv mit Eclipse erstellt. Aber ich habe es auch mit Nautilus mal erstellt (Linux) mit gleichem Ergebnis. Ich habe es sowohl unter Linux mit dem Sun-Java, als auch unter Windows 7 mit aktuellem JRE ausgeführt. Mit jeweils dem gleichen Ergebnis.
Ich habe mal das Archiv angehangen. Die erste Ausgabe vor dem Fehler ist das Ergebnis von 
	
	
	
	





```
this.getClass.getProtectionDomain().getCodeSource().getLocation()
```


----------



## Antoras (14. Mrz 2011)

Deine Manifest-Datei sieht momentan so aus:

```
Manifest-Version: 1.0
Rsrc-Class-Path: ./ mp3plugin.jar
Class-Path: .
Rsrc-Main-Class: fenster.Hauptmenue
Main-Class: org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader
```
Die Klasse JarRsrcLoader ist wohl der Grund warum dein JAR nicht funktioniert.
Wahrscheinlich hast du bei Eclipse anstatt 
	
	
	
	





```
Extract required libs
```
 die Alternative 
	
	
	
	





```
Package required libs
```
 ausgewählt, weshalb Eclipse einen eigenen JarLoader einbaut. Wieso das zu Problemen führt weiß ich nicht, aber ändere das mal. Funktioniert es dann?
Wenn das auch nicht funktioniert, dann kann ich dir das Fat-JAR-Plugin empfehlen, das komfortabler und einfacher zu bedienen ist als der bei Eclipse eingebaute JAR-Exporter.


----------



## jonius (15. Mrz 2011)

Du hast Recht. Ich verstehe den Unterschied zwar nicht wirklich, aber mit "Extract required libs" funktioniert es jetzt. Kannst du mir den Unterschied erklären? Ansonsten ist das Problem damit ja geklärt! Danke!

Korrektur: Der einzige Schönheitsfehler liegt darin, dass es unter Linux so nicht funktioniert, weil das ausführende Verzeichnis hier immer das home-Verzeichnis ist. Aber wenn man den Pfad, den man erhält nicht splittet, sondern das "file:" entfernt und Leerzeichen korrigiert, geht es.


----------



## Antoras (15. Mrz 2011)

Mit extract wird der Inhalt einer JAR entpackt und zusammen mit den anderen Dateien in einem neuen JAR wieder gepackt.
Mit package wird ein JAR direkt in ein anderes JAR gepackt also ohne es vorher zu entpacken. Bei dieser Methode kann der Code in der inneren JAR nicht ausgeführt werden, da der Pfad sich unterscheidet:

```
extract:
app.jar/path/to/MainClass
app.jar/com/lib/AnyClass

package:
app.jar/path/to/MainClass
app.jar/lib.jar/com/lib/AnyClass
```
Wenn MainClass auf AnyClass verweist (mit com.lib.AnyClass), dann kann die JVM in letzterem Fall die Klasse nicht finden, da sie in einem anderen Package liegt. Deshalb wird ein spezieller ClassLoader benötigt, der die benötigten Packages referenziert, damit sie gefunden werden können.

Dein kleiner Schönheitsfehler tritt bei mir nicht auf, ich bekomme immer den absoluten Pfad geliefert, der immer einen Slash beinhaltet.


----------



## jonius (15. Mrz 2011)

Noch eine Frage, die indirekt damit zu tun hat:
Kann ich in das bestehende Archiv, in dem das Programm liegt, mit dem Programm eine Datei hinzufügen bzw. ersetzen?


----------



## Antoras (15. Mrz 2011)

Nicht ohne es zu entpacken, die Änderungen vorzunehmen und es wieder neu zu packen. Ein JAR ist bloß ein ZIP mit anderer Endung.


----------

