21.02 JAR, JAD und Proguard
Java ME Programme werden immer als JAR-Datei mit Manifest ausgeliefert. Jedoch unterscheidet sich das Manifest in manchen Punkten vom Desktop-Derivat. Zusätzlich wird das Manifest noch leicht modifiziert als so genannte JAD-Datei (Java Application Descriptor) erzeugt. Dabei sollte die Größe der JAR-Datei so kompakt wie möglich gehalten werden. Diese Techniken werden Ihnen in diesem Kapitel näher gebracht.
Ohne IDE kompilieren
Sie haben bereits gelernt, wie Sie mit einer IDE ein J2ME Programm erstellen, kompilieren und deployen. Natürlich können Sie aber auch vollkommen ohne IDE arbeiten. Um ein Java Programm für die Mobile Edition zu kompilieren, verwenden Sie einen normalen JDK-Compiler-Aufruf mit diesen Parametern:
- -g:none – Größe der Class-Files reduzieren
- -source 1.4 – Quellcode muss Java 1.4 kompatibel sein (keine Generics, …)
- -target 1.4 – Kompilierung für Java 1.4
- -bootclasspath j2melibs – Der Boot-Classpath muss aus den benötigten Java Mobile JARs bestehen
Um das Hello-World Programm aus dem letzten Kapitel zu kompilieren, wäre bspw. folgender Code nötig:
javac -g:none -source 1.4 -target 1.4 -bootclasspath "C:/Java_ME_platform_SDK_3.0/lib/cldc_1.1.jar";"C:/Java_ME_platform_SDK_3.0/lib/midp_2.0.jar";. de/jbb/hello/HelloWorldMidlet.java
JAD und Manifest
Bevor Sie aus den erzeugten Klassen nun eine JAR Datei bauen können, benötigen Sie noch ein Manifest. Zusätzlich gibt es in der Java ME-Welt aber auch noch eine Art „externes Manifest“. Dieses ist nötig, da nicht jedes Endgerät ein JAR anhand dessen gewöhnlichen Manifests installieren kann. Außerdem ermöglicht es die Installation einer JAR-Datei die bspw. auf einem Server liegt. Es wird in Form einer .JAD-Datei bereit gestellt und enthält zwei zusätzliche Informationen, die sich im Manifest nicht finden lassen. Grundsätzlich besteht ein Java ME Manifest aus anderen Attributen wie ein Java SE Manifest:
Attribut | Manifest | JAD | Beschreibung | Beispiel |
MIDlet-Name | Verpflichtend | Verpflichtend | Name des MIDlets (frei wählbar) | MyMIDlet |
MIDlet-Version | Verpflichtend | Verpflichtend | Version des MIDlets (frei wählbar) | 1.0 |
MIDlet-Vendor | Verpflichtend | Verpflichtend | Name des MIDlet-Anbieters | Stefan Kiesel |
MicroEdition-Profile | Verpflichtend | Verpflichtend | MIDP Version | MIDP-2.0 |
MicroEdition-Configuration | Verpflichtend | Verpflichtend | CLDC Version | CLDC-1.1 |
MIDlet-1 | Verpflichtend | Verpflichtend | Angaben für die erste MIDlet App im JAR. Über MIDlet-2, MIDlet-3, … sind weitere Apps möglich. Aufbau: Name des MIDlets, Icon des MIDlets (optional), MIDlet Klasse | MyMidlet, /images/icon.png, de.jbb.MyMIDlet |
MIDlet-Jar-URL | Nicht vorhanden | Verpflichtend | Ort und Name des JAR-Files, auch eine Web-URL ist möglich | HelloWorld.jar |
MIDlet-Jar-Size | Nicht vorhanden | Verpflichtend | Größe des JARs in Bytes | 18279 |
MIDlet-Install-Notify | Optional | Optional | URL, an die eine Meldung via HTTP gesendet werden soll, wenn das MIDlet installiert wurde (Max 256 UTF-8 Zeichen) | http://www.mymidleturl.com:80/mymidlet?action=Install&key=0815 |
MIDlet-Delete-Notify | Optional | Optional | URL, an die eine Meldung via HTTP gesendet werden soll, wenn das MIDlet deinstalliert wurde (Max 256 UTF-8 Zeichen) | http://www.mymidleturl.com:80/mymidlet?action=Delete&key=0815 |
MIDlet-Delete-Confirm | Optional | Optional | Meldung, bevor das MIDlet deinstalliert wird | Sind Sie sicher, dass Sie MyMIDlet deinstallieren möchten? |
MIDlet-Info-URL | Optional | Optional | URL, die weitere Informationen über das MIDlet enthält | http://www.mymidleturl.com/mymidlet/info |
MIDlet-Description | Optional | Optional | Eine Beschreibung des MIDlets | Ganz tolles MIDlet! |
MIDlet-Icon | Optional | Optional | Ein absoluter Dateiname eines PNG-Bildes innerhalb des JARs, das vom Endgerät als Icon für das MIDlet verwendet werden sollte | /images/icon.png |
MIDlet-Push-1 | Optional | Optional | Registriert das MIDlet an der Push-Registry | datagram://:50000, de.jbb.SimpleChat, * |
MIDlet-Data-Size | Optional | Optional | Anzahl an Bytes, die das MIDlet mindestens zur Speicherung von Daten benötigt | 512 |
MIDlet-Permissions | Optional | Optional | Berechtigungen, die das MIDlet auf jeden Fall benötigt, welche aber standardmäßig eine Sicherheitsabfrage an den User nach sich ziehen | javax.microedition.io.Connector.http |
MIDlet-Permissions-Opt | Optional | Optional | Berechtigungen, die das MIDlet optional benötigt, welche aber standardmäßig eine Sicherheitsabfrage an den User nach sich ziehen | javax.microedition.pim.ContactList.read |
Ein komplettes Manifest kann so aussehen:
Manifest-Version: 1.0
Created-By: 11.0-b16 (Sun Microsystems Inc.)
MIDlet-1: HelloMIDlet, , hello.HelloMIDlet
MIDlet-Vendor: Vendor
MIDlet-Name: TestApp
MIDlet-Version: 1.0
MicroEdition-Configuration: CLDC-1.1
MicroEdition-Profile: MIDP-2.0
Das zugehörige JAD:
MIDlet-1: HelloMIDlet, , hello.HelloMIDlet
MIDlet-Jar-Size: 2443
MIDlet-Jar-URL: TestApp.jar
MIDlet-Name: TestApp
MIDlet-Vendor: Vendor
MIDlet-Version: 1.0
MicroEdition-Configuration: CLDC-1.1
MicroEdition-Profile: MIDP-2.0
Anschließend können Sie wie bei einem Java SE Programm eine JAR-Datei erzeugen.
Proguard
In der Java ME Welt ist es wichtig, dass Sie Ihre Programme möglichst kompakt ausliefern. Für dieses Ziel könnten Sie bspw. auf Packages verzichten und Klassen-/Attribut-/Methodennamen so klein wie möglich halten. Natürlich sollten Sie trotzdem weitestgehend die Code Conventions einhalten. Dieser Widerspruch erlischt, wenn Sie nachträglich Ihren Code automatisiert optimieren lassen. In diesem Bereich hat sich das kostenlose Tool Proguard etabliert. Mit diesem Tool können Sie nach der Erstellung der JAR diese auf unterschiedliche Weise optimieren, verkleinern und verschleiern (durch so genanntes obfuscating wird der Quellcode bei einer Decompilierung sehr viel schwerer lesbar) – bspw. indem nicht verwendete Klassen, Methoden und Attribute entfernt und Benötigte umbenannt werden. Proguard bietet Ihnen hier viel Gestaltungsspielraum.
Zum Abschluss des Kapitels lernen Sie, wie Sie eine erzeugte JAR mit den gängigsten Proguard-Einstellungen optimieren können. Laden Sie sich hierzu zuerst die Proguard-Bibliothek von Sourceforge herunter. Nachdem Sie die Bibliothek entpackt haben, haben Sie zwei Möglichkeiten Ihren Code zu optimieren.
Sie finden im lib-Verzeichnis eine proguardgui.jar-Datei. Diese können Sie per Doppelklick starten und die gewünschten Einstellungen in einer grafischen Oberfläche setzen. Anschließend sollten Sie die Konfiguration abspeichern und/oder direkt ein JAR optimieren. Wenn Ihnen das zu umständlich erscheint, haben Sie in vielen Fällen die Möglichkeit, Proguard in Ihre Entwicklungsumgebung zu integrieren.
Allerdings können Sie Proguard auch über die Kommandozeile bedienen, was eine Automatisierung ermöglicht. Das hierfür nötige JAR mit dem Namen proguard.jar finden Sie ebenfalls im lib-Verzeichnis. Am Besten versorgen Sie das Tool mit einer Konfigurationsdatei, die Sie beim Aufruf als Parameter übergeben:
java -jar proguard.jar @proguard.pro
In diesem Fall befindet sich die Konfiguration in der Datei proguard.pro. Diese können Sie sich entweder (wie erwähnt) vom Proguard-GUI-Tool erzeugen lassen, oder selbst per Hand anlegen. Auf der Proguard-Website finden Sie eine Übersicht aller möglichen Parameter. Für Java ME wird folgende Konfiguration häufig verwendet:
-injars YourMIDletJAR.jar
-outjars YourMIDletJAR_Obfs.jar
-libraryjars "C:/Java_ME_platform_SDK_3.0/lib/cldc_1.1.jar"
-libraryjars "C:/Java_ME_platform_SDK_3.0/lib/midp_2.0.jar"
-overloadaggressively
-repackageclasses ''
-allowaccessmodification
-microedition
-keep public class * extends javax.microedition.midlet.MIDlet
Bei den libraryjars müssen Sie natürlich die jeweils für Sie gültigen Pfade angeben.