pátek 27. dubna 2007

Java EE5 - stand-alone client

V minulém článku jsem nastínil, jakým způsobem se dá vyvíjet enterprise aplikace psaná v Jave. Samozřejmostí je využití různých metodik, podle kterých se řídí celý vývojový tým. Dříve, než mohu řešit rozsáhlé aplikace, musím ovšem míti dostatek zkušeností a znalostí. Já se chci více zaměřit na menší problémy, na které začátečník (stejně jako já) může narazit.

Budu předpokládat, že máte již základní znalosti o tom, co je to EJB, JPA a k čemu jsou enterprise aplikace určeny. Pokud by někdo hledal zdroj informací, osobně doporučuji tento tutoriál. Samotné čtení není nijak náročné. Předpokladem je základní znalost OOP, Javy, popřípadě databázových systémů typu Oracle, MySQL, .....

Osobně jsem si po přečtení celého tutoriálu udělal obrázek o tom, co je to vlastně Java EE 5 a k jakým účelům mohu něco tak rozsáhlého využít. V dnešní době je velký boom webových aplikací, které na nás srší ze všech stran. U samotné Javy se domnívám, že to není zrovna nejjednodušší oblast, kterou by se mělo začínat. Osobně jsem se raději více zaměřil na desktop, kde pomocí Swingu jsem schopen vytvořit "sexy" aplikaci, která bude splňovat základní podmínky. Každému, kdo s Javou začíná, doporučuji právě desktop.

Nyní již k samotné stand-alone aplikaci:

Přístup k EJB se dělí na dvě části:

  • Lokální (@Locale)

  • Vzdálený (@Remote)



O tom, který přístup daná EJB využívá se definuje anotací nad samotným interfacem, který samotná beana implemetuje:
@Remote
public interface UzivateleFacadeRemote {
public List findAll();
}


Rozdíl mezi Locale a Remote je ten, že Remote může volat aplikace, která běží v jiné VM. To se samozřejmě hodí ve chvíli, kdy potřebujeme napsat desktopovou aplikaci, která poběží na klientovi, který má vlastní instalaci JRE. Jiná VM není podmínkou pro běh Remote EJB.
Možná někoho napadne, proč tedy všude nevyužít Remote, když mohu volat tuto EJB kdekoli. Důvodem je výkon. Proto, pokud volám EJB uvnitř glassfishe (aplikační server), využiji k tomu Locale. Dost často mi z toho vychází, že implementuji obě interface na beanu. Navíc je také rozdílný způsob volání Locale a Remote EJB.

To by bylo k business logice. Vytvoříme si jednoduchou EJB, která bude mít Remote interface, kterou poté vystavím (deploy) na glassfish.

Nyní, se pustím do desktopové aplikace, která poběží na klientech a bude vzdáleně volat EJB ze serveru.

Prvním předpokladem je přidání celého EJB projektu v podobě distribuovaného jar souboru do aplikace. Jinými slovy, musí být někde, kde na něj samotná aplikace uvidí. V netbeans stačí do library includovat náš "projekt-ejb". Automaticky se hledá distribuovatelný jar soubor, který se defaultně nachází v adresáři dist.
Dále je potřeba přilinkovat tyto soubory:

  • appserv-admin.jar

  • appserv-deployment-client.jar

  • appserv-ext.jar

  • appserv-rt.jar

  • javaee.jar



Všechny uvedené soubory naleznete v adresáři instalovaného glassfishe (GLASSFISH_PATH/lib).

Tím bychom měli připravenou stand-alone aplikaci k tomu, aby nám byla schopna vzdáleně volat EJB.

Nyní již k samotnému kódu:
Properties properties = System.getProperties();
properties.setProperty("org.omg.CORBA.ORBInitialHost", );
properties.setProperty("org.omg.CORBA.ORBInitialPort", );
Context ctx = new InitialContext(properties);
// po pripravene inicializaci vzdalene zavolam EJB
UzivateleFacadeRemote facade = (UzivateleFacadeRemote) ctx.lookup("RemoteName");


Za a dosadíme vlastní parametry pro volání na server. Výchozím portem je 3700. Pokud testuji aplikaci na localhostu pod stejnou VM, jako mám server, není třeba properties nastavovat. Mohu zavolat InitialContext bez properties. Druhou možností je také nastavit parametricky tyto údaje. Pro další informace doporučuji glassfish: EJB FAQ.

Zapoměl jsem zmínit jednu důležitou věc. Pokud vzdáleně volám EJB, musím někde nastavit JNDI (název, pod kterým je vzdálená aplikace schopna nalézt EJB). Existuje několik možností, buď definovat daný název pomocí XML nebo pomocí anotací.

Záměrně jsem některé názvosloví popsal vlastními slovy. Důvodem je to, že při tak ohromném množství nových výrazů nejsem schopen se ihned orientovat. Také jsem ovšem danou problematiku nepsal stylem step-by-step. Zde by se jednalo o neštastné řešení, zejména ve chvíli, kdy se jedná o rozsáhlejší problematiku. Zde bych doporučil použít metodiku (pokus/omyl) :) Jinými slovy, bez přemýšlení není člověk schopen pochopit daný úkol.

Příště se podívám na JPA a FetchType. K čemu slouží LAZY a EAGER. A jak je to vlastně s defaultní hodnotou mimo a uvnitř glassfishe.

pátek 20. dubna 2007

Java EE 5 - začátky aneb konec PHP

Každý, kdo začně blíže studovat Java EE5, získá celkový přehled o tom, jak je Java rozdělena do několika vstev. Společně s tím, ale vyvstane spoustu otázek, jak provést to či ono. Některé věci totiž nejsou úplně zřejmé a pokud chci tvořit projekt, který bude provázán s dalšími vrstvami, dostanu se dost často do potíží s nastavením a vůbec spuštěním jednotlivých částí.

Na začátku je důležité si zvolit správnou technologii. Pokud zvolím Javu budu muset řešit další věc a tou je její ohromné množství frameworků. Osobně jsem toto vyřešil tak, že se držím (pokud je to jen možné) standardů SUNu.

Takže co je cílem: Vytvořit intranetovou aplikaci, která bude pokrývat požadavky firmy. Od výrobních procesů, přes ekonomické záležitosti až po různé schvalovací procesy. Klientem bude webová či desktopová aplikace. Ve chvíli, kdy potřebuji komunikovat se sériovým portem, musím volit desktop. Když budu řešit výpis sestav, použiji zase webovou aplikaci. Obě tyto aplikace musejí míti stejnou základnu (databázi). V lepším případě základnou bude business logika pro obě aplikace.

Jak jsem psal výše, zvolil jsem nejpoužívanější frameworky, které jsou navíc i standardy. Na persistenci (připojení k databázi) TopLink od Oracle. Jako databázi MySQL 5.0. Na namapování relačních tabulek do objektů JPA. Samotná business logika je řešena přes EJB3.0. Na webovou část jsem zvolil JSF společně s Facelets (i když Facelets není standard, dost pomáhá samotnému JSF). Na desktop Swing. Aplikační server je Sun Java Application Server 9 (glassfish).

Takže zvolené součásti mám úspěšně za sebou. Nyní přistoupím k samotné implementaci. První věcí, kterou musím udělat, je rozjet MySQL v glassfish. Toto udělám jednoduše tak, že nahraji java-mysql-connector do adresáře PATH_GLASSFISH/lib. V samotné admin konsoli (webová aplikace pro správu glassfishe), vytvořím connection pool a jdbc resource pro mysql a danou databázi.

Nyní přistoupím k tvorbě business logiky. Po vytvoření enterprise projektu ptovedu vytvoření persistence pomocí TopLinku. Po namapování glassfishe do IDE, vytvořím persistence.xml, který volá pomocí JNDI spojení s MySQL, kterou jsem v glassfish konsoli vytvořil.

Pro namapování relačních tabulek do JPA využiji požnosti IDE a nechám si je automaticky vygenerovat. Pro snadou správu samotných dat, vytvořím na klientovi nějakou CRUD aplikaci, takže si nechám vygenerovat i Session Beans z JPA. Použiji jak lokální, tak remote interface. Po tomto kroku, mám základ připraven. Mohu provést deploy na glassfish.

Nyní se pustím do samotného klienta. Nejprve desktopu. Vytvořím si samostatný projekt, do kterého nalinkuji potřebné glassfish knihovny a přilinkuji samotnou business logiku ve formě jar souboru. Pomocí vzdáleného volání, si nechám zavolat Session Beanu a již rovnou mohu pracovat s business logikou ve Swingu. K samotné distribuci swingové aplikace použiji Java Web Start.

Poslední věcí je webová aplikace. Přilinkuji JSF Framework, společně s Facelets. V Backing Beans volám Local EJB. Webová aplikace je v tomto ohledu o dost jednodušší, jelikož nemusím řešit vzdálené volání EJB, protože samotná aplikace běží na glassfish ve webovém kontejneru. Samozřejmě nezapomenu na convertery pro Entity a nastavení, jako navigaci, atd. Webovou aplikaci mohu vystavit na server.

Asi takto bych zjednodušeně popsal samotnou problematiku Enterprise Javy. Jako IDE jsem zvolil NetBeans a k deploymentu aplikací chytrého mravence (ant).

Tímto článkem jsem chtěl jen nastínit, že s PHP končím. Od dnešní doby se budu věnovat Javě či databázím. Pokud je někdo v podobné situaci jako já, přivítám jeho připomínky.


Příště se již budu věnovat něčemu přímočarému. Ukážu, jak ve stand-alone klientovi volat EJB z glassfishe. Na konci celý projekt zbuilduji a nechám poskytovat pomocí Java Web Start.

čtvrtek 12. dubna 2007

PDT a OOP

Každý, kdo chce efektivně pracovat s objekty, musí použít nástroj, který mu umožní automaticky doplňovat potřebné informace. Jinými slovy, použije nějaké IDE, které usnadní práci při psaní kódu.

Když si představím, že vytvořím objekt, který obsahuje několik metod, rád bych tyto metody rovnou volal. U jazyků, které dodržují striktně typovou kontrolu, je to jednoduché. Každý parametr metody musí mít typové označení, stejně tak návratová hodnota. U PHP je situace o dost horší. Jediné, co mi samotné PHP umožňuje je, že u parametru metody mohu definovat o jaký typ objektu se jedná. Navíc jsem omezen pouze na objekty a pole.
Jenže metody mi často vrací další objekty a tyto objekty někde dál používám. Samotný plugin od ZENDu (PHP Development Tool = PDT) na to jde od lesa. Dovolí mi používat komentáře, ve kterých si jasně definuji, o jaký typ se vlastně jedná. Lepší než další povídání bude ukázka.

class TridaA {
public function foo() {}
}
class TridaB {
private $tridaA;
public function __construct() {
$this->tridaA = new TridaA();
}
public function zavolejFoo() {
$this->tridaA->foo();
}
}


Z ukázky je jasné, že atribut třídy B je vlastně objekt z třídy A. Eclipse mi sice umožní automaticky zavolat metodu foo();, ale pouze v konstruktoru, protože dál už nevidí. V metodě zavolejFoo(); mám prostě smůlu. Mám ale možnost samotný atribut třídy okomentovat, čímž vyjádřím, že se jedná o objekt třídy A a pak již vše funguje, jak má.


/**
* @var TridaA
*/
private $tridaA;


Další věcí budiž parametry metody. Na začátku jsem psal, že PHP sice dovoluje definovat typ pro parametr metody, ale ne vždy tak činíme. Pokud typovou kontrolu na parametr metody definovat nechci, ale chci, aby Eclipse poznalo, že se jedná o tu či onu instanci objektu, jednoduše metodu okomentuji.


/**
* @param TridaA $tridaA
*/
public function setTridaA($tridaA) {
$tridaA->foo();
}


U definování samotného parametru metody je třeba mít na paměti, že musím také definovat, o jaký parametr se vlastně jedná.

Poslední věcí je návratová hodnota metod. K tomuto mohu opět použít komentář a říci tak Eclipse, o jaký návratový typ se vlastně jedná.


/**
* @return TridaA
*/
public function getTridaA() {
return new TridaA();
}


Pokud tedy pracujete s objekty a používáte k tomu jazyk, který má dynamické typování, jistě Vás často naštve, že nevíte, co vlastně v danou chvíli proměnná obsahuje. Toto Vám sice nezaručí, že nebudete chybovat při zjišťování typů, ale zaručí, že samotné programovací prostředí Vám řekne, co teď vlastně používáte.

Jestli jste neměli v oblibě komentáře, tak nyní si je určitě zamilujete :)

O psaní komentářů by se dala napsat celá kniha, ale o tom zase jindy.

středa 4. dubna 2007

JSF & Facelets

Samotné JavaServer Faces (JSF) je ve své podstatě jednoduchý framework na view vrstvu, který komunikuje pomocí Backing Beans. JSF v žádném případě neruší metodiky JSP-Servletů, pouze je potlačuje ve prospěch vývojářů a snaží se nabídnout alternativu pomocí JSF.

V JSF je několik vlastností (zejména uvnitř faces-config.xml), které jistě stojí za to prozkoumat:

  • Navigace

  • Lokalizace a vlastní definice messages

  • Definice managed-beans (request, session) ...

  • Psaní HTML komponent v pomocí jsf/html

  • Tvorba vlastních UI komponent



Pro vývojáře, kteří mají s podobnými typy frameworků již zkušenosti, jistě není problém se JSF doučit. Ve chvíli, kdy je pro Vás jsp-servlet nový pojem, doporučuji rovnou začít na JSF. Samotná metodika Vás nakonec stejně donutí se jsp-servlety částečně doučit.

Když to vezmu do důsledků, tak jako vývojář v PHP jsem měl k jakýmkoliv frameworkům odpor. Ne snad z toho důvodu, že bych si raději všechno psal sám, ale z toho důvodu, že jsem nikdy nevěřil, že ten či onen framework bude i nadále podporován a že mi poskytne komplexní řešení.
U JSF je situace jiná. Samotný framework (stejně jako např. JavaPersistence API), je standardem SUNu, což samo o sobě dává pocit jakési jistoty, že se samotné API neučím nadarmo. Mám jistou záruku, že bude více využíván, dále podporován, či na něm budou postaveny další implementace, které se budou snažit dodržet standard a k tomu použiji své vlastní rozšíření.
Takovouto podobnost mohu nalézt např. mezi JPA a Hibernate, kde Hibernate se stalo plně kompatibilní s JPA a navíc nabízí vlastní rozšíření (např. CriteriaAPI).

Abych jen neházel samou chválou, přece jen mně na JSF trochu vadila jedna věc a to je "šablonovací systém". Nebo chcete-li, možnost, kdy budu vkládat své stránky do stejné "formičky".

Nakonec jsem našel "Facelets", což je v podstatě rozšíření samotného JSF, které je ovšem zaměřeno právě na šablonovací systém. Samotný popis lze nalézt zde.
Pro NetBeans existuje i vlastní plugin, který je popsán zde.

Takže pokud někdo začíná s webovými aplikacemi v Jave, doporučuji JSF-EJB3-JPA. I když není Java EE 5 zrovna jednoduchá záležitost (alespoň pro mě), tak stojí za to alespoň nahlédnout, jak vlastně taková architektura vícevrstvé aplikace (z pohledu Javy), vypadá.

Na webu Jakuba Vrány o PHP, se někteří lidé domnívali, že URL v JSF je statická. Na malý problém existuje malá náplast a tou je "" v navigation-case. Stejnou fintu je třeba použít, pokud budu tvořit zabezpečenou aplikaci přes url-pattern (/secure/*) v security-constraint.