neděle 7. ledna 2007

Základy deploymentu webových aplikací na Tomcatu

V tomto článku se pokusím shrnout základy deploymentu (nasazení) webových aplikací na server Tomcat. Tomcat jsem vybral pro jeho rozšířenost, nicméně mnoho informací zde uvedených je znovupoužitelných i na jiných serverech. Rád bych upozornil, že článek se nezaobírá instalací Tomcatu a taktéž předpokládá alespoň elementární znalost servletů a JSP.

Formát webové aplikace (WARu)

Webová aplikace musí dodržovat určitou adresářovou strukturu, tak aby ji byl schopen server obsloužit. Této struktuře se říká WAR (Web Application Archive) a my se teď na ni v rychlosti podíváme.


adresář aplikace
   |  
   |--- WEB-INF
   |       |
   |       |--- classes
   |       |--- lib
   |       |
   |       web.xml
   |--- veřejné soubory (html, css, jsp, js...)     
    

Nejdůležitější částí je adresář WEB-INF (pozor vždy velká písmena), protože podle něj může server poznat, že se jedná o webovou aplikaci. Další klíčovou částí je soubor web.xml, kde je základní konfigurace webové aplikace jako mapování servletů na patřičná URL. V adresáři classes a lib leží třídy a knihovny, které aplikace používá. V kořenu adresáře aplikace leží veřejně přístupné soubory přes URL aplikace jako jsou JSP a nebo HTML stránky.

Adresář s výše popsanou strukturou lze považovat z hlediska struktury za webovou aplikaci, které bude rozumět jakýkoliv server (raději používám název servletový kontejner. Takto připravenému adresáři budeme dále říkat WAR. WAR lze nechat v takto otevřené struktuře a nebo jej můžeme zkomprimovat (zabalit) ZIPem.

WAR lze tedy mít ve dvouch formách

  • nezabalený WAR se nazývá exploded WAR
  • zabalený WAR

Poznámka na okraj: aplikační server WebSphere neumožňuje deploy exploded WARu. Jinak jsem se nesetkal, že by některý server nedokázal obě dvě varianty.

Deploy WARu

Deploy nebo nasazení WARu lze udělat několika způsoby.

  • nakopírováním WARu do deploy adresáře serveru
  • použitím webového GUI serveru pro deploy
  • použitím specifických nástrojů serveru např. Ant
  • úpravou deploy konfigurace serveru
Nakopírování WARu

V rámci Tomcatu stačí nakopírovat WAR do adresáře TOMCAT_HOME\webapps. Tím je zaručenou, že jej Tomcat nahraje. V případě zabaleného WARu je potřeba, aby měl archív příponu war například test.war. Pokud neobsahuje WAR specifický descriptor, který má samozřejmě každý server jiný, je kontext (část URL) aplikace určen jménem WARu. Ať již nakopírujeme rozbalený WAR např. test a nebo zabalený WAR test.war, bude kontext test a URL http://localhost:8080/test.

Použitím webového GUI

V Tomcatu není webové rozhraní pro deploy aplikace defaultně přístupné resp. žádný z uživatelů nemá patřičnou roli manager. K tomu, aby jí měl je potřeba upravit soubor TOMCAT_HOME\conf\tomcat-users.xml. Jednomu z uživatelů např. tomcat přidáme roli manager tedy <user username="tomcat" password="tomcat" roles="tomcat,manager"/>. Pak stačí zadat URL http://localhost:8080/manager/html a nebo použít odkaz Tomcat manager z hlavní stránky Tomcatu.

V sekci Deploy můžeme WAR deploynout dvěma způsoby, jako zabalený (WAR file to deploy) a nebo jako rozbaleny, či rozbalený se specifikací kontextu a konfigurace (Deploy directory or WAR file located on server).

Použitím Antu

Tomcat nabízí sadu antích tásků, pomocí kterých lze zabezpečit management celé aplikace. Jediná podmínka je, že opět musí existovat uživatel s rolí manager, jak bylo popsáno výše. Stačí si stáhnout předpřipravený ant soubor a upravit si hodnoty následujících properties.

  • <property name="name" value="test" /> - jméno kontextu aplikace
  • <property name="tomcat.home" value="c:\tools\tomcat-5.5.20" /> - domovský adresář Tomcatu
  • <property name="war.path" value="c:\temp\deployment\${name}.war" - cesta k WARu/>

Použitelné targety

  • deploy - deploy WARu (zvládá pouze zabalený WAR)
  • undeploy - deploy WARu
  • reload - reload WARu
  • list - vypíše seznam nainstalovaných aplikací
  • stop - vypne přijímání HTTP požadavků dané aplikace
  • start - zapne přijímání HTTP požadavků dané aplikace
  • serverinfo - vypíše informace o serveru
  • sessions - vypíše informace o sessions dané aplikace
Úpravou konfiguračních skriptů serveru

Další možnost deploynutí WARu představuje úprava konfiguračních skriptů serveru. V případě Tomcatu je to vytvoření XML souboru s definicí kontextu a jeho nakopírováni do TOMCAT_HOME\conf\[enginename]\[hostname] což je většinou TOMCAT_HOME\conf\Catalina\localhost\.

Příklad obsahu takového souboru je následující.

<Context docBase="c:\temp\deployment\test.war"
    path="test"
    privileged="true" 
    antiResourceLocking="false" 
    antiJARLocking="false"  
    reloadable="true">
</Context>    
    

Atribut docBase ukazuje buďto absolutně nebo relativně na WAR (může být jak rozbalený tak zabalený). Atribut reloadable říká jestli se při změně ve /WEB-INF/classes/ a /WEB-INF/lib provede reload aplikace (osobně mi to zafungovalo pouze při změně v lib adresáři). Atribut path určuje kontext aplikace.

Reload aplikace

Mezi nejčastější dotazy při vývoji patří otázka Jak reloadnout aplikaci bez restartu Tomcatu. Nuže způsobů je několik v závislosti na tom co se změnilo.

  • změna veřejných souborů jako JSP stránek nebo HTML souborů nevyžaduje restart. Soubory stačí zkopírovat do WARu a server se postará o zbytek.
  • změna souboru web.xml způsobí automatické znovunačtení celé webové aplikace
  • změna tříd případně knihoven nezpůsobí nic, pokud se neprovede znovunačtení webové aplikace. To můžeme udělat několika způsoby.
    • použijeme výše uvedený ant soubor a target reload
    • zavoláme URL http://localhost:8080/manager/reload?path=/context aplikace např. http://localhost:8080/manager/reload?path=/test (opět musíme mít uživatele s rolí manager viz výše)
    • pokud je WAR zabalený, způsobí nakopírování nové verze do deploy adresáře serveru reload celé aplikace
    • použít kontext definici, která zajistí reload aplikace při změně WEB-INF/classes a WEB-INF/lib (osobně mi to zafungovalo pouze při změně v lib adresáři). Kontext nadefinujeme následujícím způsobem. Ve WARu vytvoříme adresář META-INF a v něm soubor context.xml, do kterého dáme následující element <Context docBase="test" privileged="true" reloadable="true" /> (hodnotu atributu docBase si změnte na kontext aplikace).

Dalším doplňkovým způsobem vhodným pro drobné změny ve třídách je využití HotSwap vlastnosti JVM. Když je Tomcat nebo jakákoliv jiná aplikace puštěna v debug módu, může agent (většinou vývojové prostředí) dělat změny nahraného bajt kódu. Díky této vlastnosti se dají měnit střeva metod, pokud nezasahují do definice třídy např. změna rozhraní apod.

Užitečné odkazy