Web Start használata intranetes Java EE alkalmazásoknál
A Java Web Start Javaban írt szoftverek terjesztésére, automatikus telepítésére és frissítésére kidolgozott technológia. XML formátumú JNLP leírófájlok segítségével adhatjuk meg a letöltésnek és az alkalmazás indításának a paramétereit, amelyeket a kliensoldali, a JRE részeként telepíthető javaws program értelmez.
Web Start elérésű alkalmazásokkal elsősorban internetes demóknál találkozhat az internetjáró, ám igazán hasznos lehet akkor is, ha belső hálózaton futó kliens-szerver rendszereket fejlesztünk, üzemeltetünk.
A kliensprogram első, és a rendszeresen feltett frissítések rendszeres telepítése is automatikussá, felhasználóbaráttá tehető a segítségével. Az automatikus telepítés folyamatának megértéséhez nézzük meg a Sun Web Start technológiát bemutató oldalán található ábrát:
Hogy hogyan is használhatjuk ki mindezt intranetes J2EE alkalmazásainknál? Lássuk a részleteket!
1. Működés
Képzeljük el a következő helyzetet: készítettünk egy alkalmazást, amelynek a szerveroldali részét, egy ear-t az alkalmazásszerveren (pl. JBOSS) deployoltuk (ha valaki tud erre szép magyar szót, akkor kérjük, írja meg a pio[kukac]nir[pont]hu e-mail címre!). Az alkalmazásunk kliensoldali komponensének futtatásához szükség lesz a kliensgépeken egy futtatható jarra, és egyéb könyvtár jarokra. Azt szeretnénk, hogy ezek a jarok mindig a legfrissebbek legyenek, és lehetőleg ne egyesével kelljen őket a kliensekre felmásolni, hanem a program indításakor frissüljenek.
Ha Web Start-tal tesszük elérhetővé a jarokat, akkor mindez így is történik: a felhasználó a böngészőben megnyit egy URL-t, és az ott található jnlp fájlt megnyitva a javaws program ellenőrzi, vannak-e frissítések, ha igen, akkor letölti azokat, és így indítja az alkalmazást.
2. A jar fájlok
A Web Start világában csak kétféle fájl létezik: jar, és JNLP. A jar fájlok közül kétfélével lesz dolgunk: egy futtatható fájllal, és egy vagy több könyvtár csomaggal.
Ha megvannak a jarjaink, első lépésként alá kell írnunk őket. Ehhez egy keystore kulcs fájlra lesz szükség, amelyet a JDK részét képező keytool paranccsal készíthetünk el, például a következő módon:
$ keytool -genkey -keystore nir.keystore -alias NiR -validity 3650
Ennek lefuttatása után kapunk egy keystore_file nevű fájlt, amellyel (az alapértelmezett 90 nap helyett) 10 évig írhatjuk alá jarjainkat. A futtatás során meg kell adjunk egy jelszót, és a cégünk adatait – hasonlóan mint például egy openssl tanúsítvány elkészítésekor.
Ha a -keystore kapcsolóval nem adunk meg fájlnevet, akkor a $HOME könyvtárunkban készül egy .keystore fájl. Egy ilyen keystore több kulcsot is tartalmazhat, amelyeket a keytool -list paranccsal listázhatunk. Bővebben a keytool használatáról itt lehet tájékozódni vagy persze man keytool – érdemes megnézni, kulcsgenerálási algoritmusokat adhatunk meg a futtatás során, illetve az aliasok alapján külön jelszó rendelhető az egyes kulcsokhoz.
Következő lépés, hogy aláírjuk jarjainkat. Erre a jarsigner programot használhatjuk:
$ jarsigner -keystore nir.keystore -storepass _jelszo_ alkalmazas.jar NiR
Az összes elérhetővé tenni kívánt jart alá kell írnunk. Kisebb kavarodást az okozhat, ha a terjesztendő könyvtárak némelyike már alá van írva más által. Ez esetben a mi aláírásunk sajnos nem tudja az eredetit felülírni, így külön trükkökhöz kell folyamodnunk, jelesül: a más által aláírt jarokhoz külön JNLP-t kell rendelnünk. De erről később.
Ant-tal automatizalhatjuk a jarok aláírását, íme egy aláíró target:
<target name="webstart">
<signjar alias="NiR"
keystore="${webstart.dir}/keystore_file"
storepass="_jelszo_"
verbose="false"
lazy="true">
<fileset dir="${webstart.dir}/server/"
includes="alkalmazas.jar"/>
<fileset dir="${webstart.dir}/server/lib">
<include name="**/*.jar"/>
</fileset>
</signjar>
</target>
A könyvtárak és fájlok neveit, illetve a jelszót értelemszerűen be kell helyettesíteni. A lazy kapcsolóval azt adjuk meg, hogy a már aláírt jarokat nem szeretnénk újra aláírni.
3. JNLP fájlok
A JNLP deskriptorok valójában XML fájlok, amelyek leírják hogyan, és mely jar-okat kell a webstartnak letöltenie/futtatnia. Nézzünk egyből egy példát.
<?xml version="1.0" encoding="ISO-8859-2"?>
<jnlp spec="1.0+"
codebase="http://192.168.1.103:8080/webstart"
href="progi.jnlp">
<information>
<title>NiR Progi 1.0</title>
<vendor>NiR Informatikai Megoldások Kft.</vendor>
<homepage href="http://nir.hu"/>
<description>Pénzügy alkalmazás</description>
<description kind="short"></description>
<icon href="icon.gif"/>
<icon kind="splash" href="splash.gif"/>
<offline-allowed/>
</information>
<security>
<all-permissions/>
</security>
<resources>
<j2se href="http://java.sun.com/products/autodl/j2se" version="1.5+"/>
<jar href="progi-client.jar"/>
<extension name="included" href="included.jnlp"/>
<property name="swing.auxiliarylaf" value="hu.nir.sns.SNSAuxLookAndFeel"/>
</resources>
<application-desc/>
</jnlp>
Az XML formátumának megadása után a <jnlp> tag következik. Ezen az XML elemen belül van a teljes leírás. A nyitó tagen belül adjuk meg a JNLP specifikációt, a fájl elérését, és a codebase attribútum értékeként adjuk meg az URL-t, ahol a letöltendő jarok, és az esetleg hivatkozott egyéb jnlp fájlok találhatók.
Az <information> elemen belül az alkalmazásunkkal kapcsolatos információkat adhatunk meg. A legtöbb tag magáért beszél. Amire mindenképp figyeljünk: ha az <offline-allowed/> tag itt szerepel, akkor az alkalmazás akkor is elindul, ha s szerver nem érhető el éppen, illetve a frissítések ellenőrzése is leáll egy idő után. Ezért a legtöbb esetben, főleg J2EE alkalmazások esetén ezt valószínűleg ki fogjuk hagyni.
A <security> elemben az <all-permissions/> tag adja meg, hogy az alkalmazásunk minden joggal rendelkezzen a kliensgépen.
Az <application-desc/> önmagában lezárt tag jelzi, hogy ez a JNLP egy indítható alkalmazásra mutat, azaz nem beágyazott, másik jnlp fájlból hivatkozott forrásokra.
A <resources> elem a lényeget: az elérendő komponenseket/csomagokat adja meg. Példánkban a j2se verzió meghatározása után megadjuk a kliens jar elérését, majd az <extension> elemben egy másik jnlp fájlra hivatkozunk. Erre azért volt szükség, hogy különböző indítási környezeteket definiálhassunk, különböző jnlp-k segítségével, amelyek mondjuk más-más <property> elemeket definiálnak, de ugyanazokat a könyvtár jarokat használják.
A hivatkozott JNLP tartalma:
<?xml version="1.0" encoding="ISO-8859-2"?>
<jnlp spec="1.0+"
codebase="http://192.168.1.103:8080/webstart/"
href="jars.jnlp">
<information>
<title>jars</title>
<vendor>NiR Informatikai Megoldások Kft -- info@nir.hu</vendor>
</information>
<security>
<all-permissions/>
</security>
<resources>
<jar href="lib/ant.jar"/>
<jar href="lib/wsdl4j.jar"/>
<jar href="lib/velocity-1.4.jar"/>
<extension name="mail" href="mail.jnlp"/>
...
...
...
<property name="java.security.auth.login.config"
value="http://192.168.1.103:8080/webstart/auth.conf"/>
</resources>
<component-desc/>
</jnlp>
Mint látható, ide az összes közös részt kiemelhetjük, például <property> elemeket is definiáltunk. Aki már ütközött auth.conf elérési problémákba, az tudja, hasznos lehet, ha azt is a központi szerveren tesszük hozzáférhetővé.
Fontos, hogy ebben a fájlban az <application-desc/> tag helyett <component-desc/> szerepel, mivel ez nem indítandó, hanem beágyazott tartalmat ír le. Ennek és az <extension> elemnek leírása egy SUN-os 'JNLP File Syntax' oldalról:
The component-desc element denotes that this jnlp file is not an application or an applet but an extension that can be used as a resource in an application, applet or another extension.
A component extension is typically used to factor out a set of resources that are shared between multiple applications or that have separate security needs.
Olykor az is előfordul, hogy olyan könyvtárakat használ az alkalmazásunk, amelyeket a készítő/kibocsátó aláírt jarba csomagolt. Ilyenkor az ezekre hivatkozó bejegyzést nem rakhatjuk az általunk aláírt jarokat leíró JNLP-kbe. Az <extension> elem ennek megoldására is szolgál – mint látjuk a mail.jnlp-re hivatkozunk, amely a következőképpen fest:
<?xml version="1.0" encoding="UTF-8"?>
<jnlp spec="1.0+"
codebase="http://192.168.1.103:8080/webstart/"
href="mail.jnlp">
<information>
<title>Mail</title>
<vendor>Sun Microsystems, Inc.</vendor>
</information>
<resources>
<jar href="lib/mail.jar"/>
</resources>
<component-desc/>
</jnlp>
Több ilyen hivatkozást is megadhatunk. Hogy mely jarok vannak már aláírva, megtudhatjuk, ha a következő parancsot lefuttatjuk mindegyikre:
jarsigner -verify -certs -verbose foo.jar
Egyéb elemeket, tageket is használhatunk, például operációsrendszer-függő natív könyvtárak használatához. Ezek megismeréséhez lásd az oldal alján található linkeket.
4. Webszerver
Ha úgyis Java alkalmazásszervert használunk, akkor a legegyszerűbb, ha az abban található webszervert (pl. JBOSS esetén Tomcatet) használjuk a jnlp és jar fájlok elérhetővé tételére. Készítsünk egy webstart.war könyvtárat, ebben egy META-INF és egy WEB-INF könyvtárral. Előbbibe tegyünk egy MANIFEST.MF fájlt a következő tartalommal:
Manifest-Version: 1.0 Created-By: 1.5.0_06 (Sun Microsystems Inc.)
A WEB-INF könyvtárban lévő web.xml fájl tartalma:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<display-name>Tomcat default servlet webapp</display-name>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
Ezek után a webstart.war könyvtárba rakhatjuk a jnlp fájlokat és a kliens jart, és – csak hogy szép legyen – ezen belül a lib könyvtárba az egyéb szükséges könyvtár jarokat. Készíthetünk egy HTML oldalt is a jnlp-k eléréséhez, és miután a war-t deployoltuk a szerveren, kész is van a intranetes, kényelmes J2EE kliens kiszolgálás. Bármikor frissítjük a szerveren a kliensoldali jarokat, azok indításkor frissülni fognak. Ha a jnlp fájl tartalma változik a szerveren, például új jar kerül a többi mellé, akkor a javaws ezzel is boldogul.
Egyéb ajánlott oldalak további olvasásra/tájékozódásra:
- http://java.sun.com/products/javawebstart/ – Java Web Start Technology
- http://www.cokeandcode.com/info/webstart-howto.html – A Walkthrough with WebStart/JNLP
- http://java.sun.com/j2se/1.5.0/docs/guide/javaws/developersguide/faq.html – JavaTM Web Start version 1.5.0 - Frequently Asked Questions (FAQ)
- http://java.sun.com/javase/6/docs/technotes/guides/javaws/developersguide/contents.html – Java Web Start Guide
- http://lopica.sourceforge.net/faq.html – Unofficial Java Web Start/JNLP FAQ




