Zcela náhodou jsem zjistil, že už pěknou chvíli existuje speciální komprese pro javovské třídy distribuované v JARech. Jde o zajímavý způsob ztrátové komprese (ano, skutečně, ztrátova komprese pro zkompilované třídy) která umožňuje snížit velikost výsledného souboru až na 1/9 původní velikosti (pokud tam máte pouze třídy, a ne například bitmapy).
Oficiální dokumentace k programu Pack200 vysvětluje většinu důležitých věcí, přesto bych rád vyzdvihnul několik (na první pohled možná ne úplně jasných) věcí.
Za prvé, jde o zcela separátní stupeň komprese, asi jako když vezmete JAR soubor a zabalíte ho WinRARem. Takový packnutý soubor nejde (na rozdíl od jaru) spustit, a téměř jediné co s ním můžete udělat, je rozbalit ho (buď za použití externích prográmků dodávaných s JRE, nebo pomocí javovské třídy java.util.jar.Pack200. Pack200 je naštěstí natolik chytrý, že si poradí jak s komprimovanými jary, tak s nekomprimovanými (nejdřív jsem si myslel, že ten jar musí být nekomprimovaný, však to znáte, komprimovat už komprimované je nesmysl.. tak jsem to radši vyzkoušel).
Druhá věc, co s ním můžete udělat, je nahrát ho na web. Pack200 totiž vznikl na základě JSR 200: Network Transfer Format for JavaTM Archives – čili primárně jako kompresní formát pro přenos po síti. Vzhledem k tomu, že nejčastější forma přenosu bývá HTTP, je přirozené použít přímo HTTP kompresi. Od Javy 1.5 podpora pro Pack200 (a gzip) zabudovaná jak do javovského pluginu pro prohlížeč, tak do webstart. V praxi to znamená, že plugin nebo webstart pošle v http hlavičce informaci, že přijímá soubory komprimované pomocí pack200 a pokud server takovému požadavku porozumí, pak pošle komprimovanou verzi (spolu s informací o použitém způsobu komprese). Klient po obdržení dat nejdřív archiv rozbalí, a následně ho spustí. (Rád bych zdůraznil, že tohle je skutečně záležitost http protokolua přenosu po síti, pokud máte applety u sebe na disku a přistupujete k nim lokálně, musíte je mít rozbalené).
Háček je v tom, jak správně nastavit webserver (zejména na apache na hostingu). Po chvíli hledání jsem našel 2 možné způsoby. První z nich využívá content negotiation a vypadá poměrně složitě (navíc mod_negotiation nemusí být vůbec na vašem hostingu přístupný). Druhý způsob vypadá podstatně schůdněji, a využívá poměrně všudypřítomný mod_rewrite. Dovolím si odcitovat příslušný .htaccess:
AddType application/x-java-archive .jar
AddType application/x-java-jnlp-file .jnlp
AddEncoding pack200-gzip .jar
RemoveEncoding .gz
RewriteEngine on
RewriteCond %{HTTP:Accept-Encoding} pack200-gzip
RewriteCond %{REQUEST_FILENAME}.pack.gz -f
RewriteRule ^(.*\.jar)$ $1.pack.gz [NC,L]
RewriteCond %{HTTP:Accept-Encoding} gzip
RewriteCond %{REQUEST_FILENAME}.gz -f
RewriteRule ^(.*\.jar)$ $1.gz [NC,L]
(a až zjistím, jak textile přinutit, aby neformátovalo text <pre> tak to možná nebude vypadat tak hnusně)