Der Protokoll-Handler für Jar-Dateien
Die Methode url.openConnection() öffnete den Datenstrom und sucht einen passenden Protokoll-Behandler sucht. Um die typischen Behandler-Eigenschaften zu nutzen, passen wir den Typ der Rückgabe an, sodass wir zum Beispiel eine URLConnection zu einer HttpURLConnection aufwerten, wenn wir wissen, dass der zu erwartende Behandler eine HTTP-Verbindung übernimmt.
So wie HttpURLConnection das Protokoll HTTP übernimmt, kümmert sich die JarURLConnection um das Protokoll »jar«, das sich auf Java-Archive bezieht. Das Format für die URL beginnt mit dem Namen des Protokolls, dem hinter dem Doppelpunkt die URL folgt. Den Abschluss bildet zwingend die Zeichenfolge »!/«:
URL url = new URL("jar:http://midlet.org/repository/anfy/amark/Amark.jar?md=65!/");
Des Weiteren lässt sich im Archiv eine bestimmte Datei auswählen. Die Angabe folgt dann hinter dem Trenner »!/«:
String host = "http://midlet.org/repository/anfy/amark/Amark.jar?md=65"; String path = "a/a.class"; URL url = new URL( "jar:" + host + "!/" + path );
Nach dem Aufbau des URL-Objekts liefert url.openConnection() das URLConnection-Objekt, das wir aber explizit an JarURLConnection anpassen. Das bietet die Möglichkeit, mit getJarFile() auf das Java-Archiv zuzugreifen:
JarURLConnection conn = (JarURLConnection) url.openConnection(); JarFile jarFile = conn.getJarFile();
Das JarFile repräsentiert die Datei mit ihren Dateien, die vom Typ JarEntry sind. Mit der Methode getEntry(String) lässt sich eine bestimmte Datei auswählen. Eine Liste der eingebundenen Dateien liefert entries() über eine Enumeration.
for ( Enumeration it = jarFile.entries(); it.hasMoreElements(); )
{
JarEntry entry = ( JarEntry ) it.nextElement();
if ( ! entry.isDirectory() )
System.out.println( entry + ", " + entry.getSize() );
}
In unserem Beispiel liefert die Schleife die Ausgabe, die mit
a/a.class, 7504 b/a.class, 1308 b/b.class, 3293
beginnt. Während getJarFile() das gesamte Archiv repräsentiert, kann ja in der URL gleich eine ganz konkrete Datei ausgewählt sein. Dann ist JarFile gar nicht nötig, denn das Interesse ist nun bei einer konkreten Datei. Die liefert getJarEntry() auf dem JarURLConnection-Objekt wieder als JarEntry-Objekt.
So viele Methoden bietet JarURLConnection nicht an, doch kann getManifest() (liefert ein Manifest-Objekt) nützlich sein, um an die Beschreibung des Archivs zu gelangen. Um den Inhalt zu beziehen, vermuten wir bei JarEntry eine Methode, die einen Strom liefert. Dem ist aber nicht so. Stattdessen gibt es eine Methode getInputStream() bei JarFile, die als Parameter den JarEntry erwartet:
JarFile jarFile = conn.getJarFile(); ZipEntry entry = jarFile.getEntry( "a/a.class" ); InputStream in = new BufferedInputStream( jarFile.getInputStream(entry) );