Západočeská univerzita v Plzni Fakulta aplikovaných věd Katedra informatiky a výpočetní techniky DIPLOMOVÁ PRÁCE

Rozměr: px
Začít zobrazení ze stránky:

Download "Západočeská univerzita v Plzni Fakulta aplikovaných věd Katedra informatiky a výpočetní techniky DIPLOMOVÁ PRÁCE"

Transkript

1 Západočeská univerzita v Plzni Fakulta aplikovaných věd Katedra informatiky a výpočetní techniky DIPLOMOVÁ PRÁCE Plzeň, 2007 Břetislav Wajtr

2 Západočeská univerzita v Plzni Fakulta aplikovaných věd Katedra informatiky a výpočetní techniky DIPLOMOVÁ PRÁCE Implementace jednoduchého komponentového modelu Plzeň, 2007 Břetislav Wajtr

3 Prohlašuji, že jsem diplomovou práci vypracoval samostatně a výhradně s použitím citovaných pramenů. V Plzni dne Břetislav Wajtr

4 Abstrakt Implementation of simple component model This work aims to create and implement simple, in-process component model based on OSGi Service Platform specification. In first part of the thesis author describes theory around component development advantages, disadvantages and common principles. It is here, where it is described how applications based on component technology are developed and what must be taken into account when doing so. Examples of several existing component models are listed at the end of the first part. Second part of the thesis is the specification of the created simple component model itself. It contains rules and regulations which must be obeyed when implementing this specification. Features of a component model created as part of this thesis are: based on OSGi but modified, simplistic, in-process, supports Groovy language, fine-grained component dependencies and others. Since the main part of the thesis is implementation of such component model, last part of the paper holds programmers documentation to it. High-level architecture of the system is placed here as well as coding issues encountered during implementation.

5 Obsah Abstrakt... 1 Úvod Typografické a jmenné konvence Obecně o komponentách Motivace pro komponentové technologie Co je to komponenta Komponentové architektury Jaké problémy nechceme řešit Jaké problémy chceme řešit Ekosystém vývoje Shrnutí rolí Komponentové modely EJB Swing OSGi Ostatní OSGi specifikace OSGi Service Platform CoSi Components Simplified Požadavky Specifikace CoSi Základní přehled Komponenta Obsah komponenty...27 Aktivátor komponenty...28 Rozhraní (interfaces) a služby...28 Typy...30 Události (events)...30 Atributy Specifikace komponenty soubor Manifest.mf Distribuční forma komponenty Kontejner Životní cyklus komponenty ClassLoader architektura Proces vyhodnocení komponenty Rozhraní kontejneru...45 Rozhraní BundleControl...46

6 Rozhraní BundleContext...47 Rozhraní Bundle...52 Rozhraní ServiceReference...54 Rozhraní ModuleClassLoader...55 BundleMetadata Základní služby System Service Message Service Rozdíly proti OSGi Implementace CoSi Jádro kontejneru Implementace systémových služeb Služba SystemService Služba MessageService Implementace doplňkových služeb Služba SimpleShell Služba LogService Služba HttpService Ukázkový příklad Závěr...82 Literatura...83 Příloha A: Syntax souboru manifest.mf...84

7 1 Úvod Komponentové technologie začínají čím dál tím více prostupovat programátorským světem. I když jsou tyto technologie už nějakou dobu využívány, většího rozmachu se jim dostává až v posledních letech. V jiných inženýrských oborech je celkem běžné, že složitější objekty se skládají z jednodušších (jako například obvod se skládá z odporů, cívek atd.). V softwarovém průmyslu už to ovšem tak jednoduché není. Dalo by se jednoduše říci, že úkolem komponentových technologií je snaha přiblížit se právě takovému skládání komponent. V následujícím textu se čtenář nejdříve seznámí s obecnými principy komponentových technologií, tedy s tím co to komponenta je, jak je využívána a jak vypadá proces výroby softwaru založeného na komponentové technologii (kapitola Obecně o komponentách ). V kapitole Komponentové modely jsou krátce popsány různé typy existujících, komerčně využívaných komponentových modelů. Teorie o komponentových modelech je zakončena detailnějším popisem architektury komponentového modelu OSGi, který byl vybrán jako vzor pro vypracovaní praktické části práce. Cílem této práce je navrhnout, popsat a implementovat jednoduchý komponentový model. Praktickou část práce tedy tvoří specifikace takového modelu (kapitoly 5 a 6) a samozřejmě také popis implementace takto vytvořené specifikace (kapitola 7 - Implementace CoSi ). 1.1 Typografické a jmenné konvence V textu jsou různými typy písma odlišeny ty části textu či slov, které si odlišení zaslouží. Jedná se o: zdůraznění zdrojový text [EJB] Slova či pojmy, kterým by čtenář měl věnovat pozornost. Jedná se buď výrazy, které jsou v textu použity poprvé a budou dále vysvětleny či o prosté zdůraznění slova. Části kódu textu jsou tisknuty tímto písmem. Jedná se o buď o delší výpisy zdrojových textů, či o jednotlivá slova uvnitř odstavců, která se na zdrojový text odkazují. Příklad citace v textu. 1

8 Jmenná konvence typů a proměnných použitá ve zdrojovém kódu práce i samotném textu je následující: Jména tříd začínají velkým písmenem. Například: Bundle. Metody začínají malým písmenem a jednotlivá slova metody začínají velkým písmenem. Například: getnewinstance() { }. Proměnné třídy začínají malým písmenem a jednotlivá slova proměnné začínají velkým písmenem. Například: public boolean isexecutionallowed. Parametry metod mají složitější strukturu - všechny parametry jsou uvozeny velkým písmenem P za nímž následuje jednopísmenný popis typu parametru. To platí pro jednoduché typy jako je int, boolean, long atd. či jejich obalovací třídy (Integer, Boolean, Long atd.) Pokud parametr nemá jednoduchý typ, neuvádí se žádný popis typu parametru. Za popisem parametru je podtržítko ( _ ), za kterým následuje samotné jméno parametru. To opět začíná malým písmenem a jednotlivá slova začínají písmenem velkým. Příklady uvedené na hlavičkách metod: public void somemethod(int Pi_paramOne, Integer Pi_paramTwo) public void somemethod(string Ps_paramThree, FooBar P_paramFour) Aby se vizuálně odlišily proměnné uvnitř metod od proměnných třídy, jsou tyto parametry pojmenovávány se stejnými pravidly jako parametry metod, ale místo úvodního písmene P je použito písmeno F. Příklad: String Fs_localString Posledním pravidlem je pojmenovávání privátních metod třídy, které dodržují stejná pravidla jako jiné metody, ale jsou uvozena podtržítkem. Příklad: private void _myprivatemethod() { } 2

9 2 Obecně o komponentách Dá se říci, že komponentové technologie mohou být dalším logickým evolučním krokem ve světě programování. Není to krok revoluční, ale posouvá způsob programování zase o kus dál. Historie těchto technologií sahá sice až do roku 1990 (pěkný přehled historie programovacích nástrojů co se týče komponent najdete v [IBM]) nicméně většího rozmachu a využití se těmto technologiím dostává až od roku 1997, kdy byla firmou Sun poprvé prezentována technologie EJB. Obecně se dá říci, že ještě v roce 2007 je tato technologie velmi živá a neustále se vyvíjí podle toho, jak se na ní mění požadavky. Celá kapitola Obecně o komponentách je mým překladem úvodních kapitol z knihy [ROM]. Tato kniha se hlavně zabývá popisem a výukou technologie Enterprise Java Beans (viz kapitola 3.1 EJB), její úvodní části jsou ale velmi pěkným úvodem do smyslu komponentových technologií. 2.1 Motivace pro komponentové technologie Spolu s výrazným zvyšováním výkonu osobních počítačů rapidně rostou i nároky na software, který je ta těchto počítačích používán. Aplikace jsou čím dál tím komplikovanější, poskytují čím dál tím komplexnější služby a vývoj těchto aplikací je o náročnější a čas potřebný na jejich realizaci se zvyšuje. S rozvojem internetu a podnikových intranetů také sílí požadavky na podporu sítí v těchto aplikacích. Málokterá firma si dnes dovolí koupit větší podnikový software, který by nebyl postaven na technologii server-client, který by nevyužíval společných databázových zdrojů a který by například nepoužíval ve firmě již zavedený autentizační systém (jako je např. LDAP). Nároky na systémy rostou, přesto můžeme ve většině aplikací najít společné prvky. Každý softwarový inženýr si dnes klade otázku, zda je skutečně nutné psát v podstatě stejné věci pro každou aplikaci znovu a znovu. Těmito věcmi by mohly například být: komunikace s databází, autentizace a autorizace uživatelů v podnikové síti, logování běhu aplikace nebo například komunikace mezi částmi aplikace. Zatím si jednoduše zaveďme pojem middleware jako tyto stejné služby; podrobněji tento pojem přiblížíme níže. V minulosti si mnoho společností psalo svůj vlastní middleware. Například firma zabývající se finančními službami si mohla postavit některé z middleware služeb, aby jí pomohly dát dohromady systém obchodování na burze. Společnosti, které dnes vyvíjejí svůj vlastní middleware riskují, že jejich projekt selže. High-end middleware je velice komplikovaný, těžko se udržuje, k jeho vytvoření jsou zapotřebí znalosti na úrovni expertů a zcela se odchyluje od opravdových zájmů 3

10 většiny projektů. Proč namísto psaní vlastních middleware služeb si je prostě nekoupit? Aplikační server byl vytvořen, aby bylo možné tyto služby nakupovat už hotové, spíše než si stavět své vlastní. Aplikační servery vám poskytují obecné middleware služby jako je sdílení zdrojů, síťové služby, autentizace a autorizace a další. Aplikační servery vám umožňují zaměřit se na business logiku projektu a dovolují vám nestarat se o middleware, který potřebujete k robustnímu serverovému nasazení. Vy píšete kód, který je specifický pro váš průmysl a nasazujete tento kód do běhového prostředí aplikačního serveru. Obr. 2.1: Architektura distribuovaného systému Obrázek 2.1 ukazuje typickou business aplikaci. Tato aplikace by mohla existovat v jakémkoli průmyslu a mohla by řešit jakýkoliv business problém. Zde jsou některé příklady: Systém obchodování na burze Bankovní aplikace Zákaznické call centrum Analýzy rizik v pojišťovnictví 2.2 Co je to komponenta Hlavní motivací pro komponentové technologie je myšlenka, že software je vlastně složen z větších nebo menších funkčních celků - komponent, které je možno použít i u 4

11 jiných aplikací. Je zde tedy kladen důraz na znovupoužitelnost. Proč bychom měli psát tu samou funkčnost znovu a znovu, když jsme ji my, nebo někdo před námi, už někdy napsali. Tento rys se do jisté míry vyskytuje i u objektového programování, nicméně komponentové technologie tuto myšlenku rozvíjí ještě dále. Výsledkem je tedy aplikace jako síť komponent, které jsou mezi sebou propojeny a které mezi sebou spolupracují. O komponentě víme co dělá, víme jak jí máme propojit s jinými komponentami a víme jak z komponenty získáme výsledky. Všimněte si, že jsem nezmínil to, že víme jak to komponenta dělá. To je další z velmi silných vlastností komponentových technologií. Abyste komponentu mohli v aplikaci použít, nemusíte (a častokrát ani nesmíte) vůbec znát její kód, stačí vědět jaké rozhraní poskytuje. Mohli bychom si tedy komponentu definovat ([WiKi]) jako část systému nabízející předdefinované služby se schopností komunikovat s dalšími komponentami. Clemens Szyperski a David Messerschmitt nazývají komponentami to, co splňuje následujících pět kritérií ([WiKi]): Znovupoužitelná Nezávislá na kontextu Lze jí skládat s ostatními komponentami Zapouzdřená, tzn. kromě rozhraní nevíme nic o vnitřku komponenty Jednotka nezávislého nasazení a verzování 2.3 Komponentové architektury Jak jsme si již řekli, myšlenka vícevrstvých server-side systémů je již několik let stará. Od té doby se objevilo na trhu více než 50 aplikačních serverů. Nejdříve každý aplikační server poskytoval komponentové služby nestandardním, proprietárním způsobem. Toto se stávalo, protože nebyla k dispozici žádná obecně uznávaná definice toho, co by vlastně komponenta měla být, jak by měla být provázána se službami, či jak by měla spolupracovat s aplikačním serverem. Výsledek? Jakmile jste vsadili na určitý aplikační server, váš kód byl "uzamčen" pro toto řešení. Toto velmi výrazně snížilo přenositelnost, což bylo trnem v oku pro svět Javy, kde otevřenost a přenositelnost jsou hlavními myšlenkami. Co je potřeba je dohoda, nebo-li množina rozhraní mezi aplikačními servery a komponentami. Tato dohoda umožní, aby mohla být jakákoliv komponenta použita s kterýmkoliv aplikačním serverem. Toto umožní komponentám, aby mohly být připojovány a odpojovány z různých aplikačních serverů bez toho, aby bylo potřeba komponenty jakkoliv měnit nebo dokonce překompilovávat. Taková dohoda se nazývá komponentová architektura. 5

12 V současnosti máme na výběr z několika architektur - postavených na Javě nebo na jiných jazycích, s otevřeným kódem či proprietárních. 2.4 Jaké problémy nechceme řešit Zaměřme se na to, že aplikace, kterými se zabýváme, jsou distribuovanými systémy. Rozdělíme to, co by normálně byla velká, monolitická aplikace na vrstvy a každou z těchto vrstev oddělíme od ostatních tak, že každá je zcela nezávislá a zřetelná. Pokud takovou aplikaci rozdělíme na distribuovaný systém s mnoha klienty, kteří se připojují k více serverům a databázím přes síť, musíme řešit problémy a otázky, které jsme dříve řešit nemuseli a které nám teď nově vyvstávají. Následuje krátký seznam těchto problémů: Vzdálené volání metod (Remote Method Invocations). Potřebujeme logiku, která spojí klienta a server přes síťové propojení. Toto zahrnuje obsluhu volání metod, ukládání parametrů atd. Vyrovnávání zátěže (Load Balancing). Klienti musí být přesměrováni na server, který je nejméně zatížen. Jestliže je server přetížen, měl by být zvolen jiný server. Průhledné selhání serverů. Pokud server selže, nebo pokud selže síťové připojení mohou být klienti přesměrováni na jiné servery bez přerušení služby? Pokud ano, jak rychle se systém zotaví? Vteřiny? Minuty? Kde je hranice, kterou je váš businnes problém schopen akceptovat? Transakce. Co když dva klienti přistupují ke stejné řádce v databázi zároveň? Nebo co se stane, když zhavaruje databáze? Transakce vás chrání před těmito problémy. Clustering. Co když server obsahoval nějaký stav než zhavaroval? Je tento stav replikován na všech serverech, takže klienti mohou v klidu použít jiný server? Dynamický redeployment. Jak budete provádět update nebo upgrade softwaru na běžícím systému? Potřebujete server vypnout nebo ho můžete nechat běžet? Čisté vypnutí. Pokud potřebujete vypnout server, můžete to udělat jemným, čistým způsobem tak, že nepřerušíte služby pro klienty, kteří tyto služby na tomto serveru momentálně používají? Logging a auditing. Jestliže stane něco špatného, máte k dispozici log, který můžete zkonzultovat a stanovit z něj příčinu problému? Log by vám mohl pomoci ladit problém takže chyba by se už nemusela nikdy opakovat. Management systému. V případě katastrofického selhání, kdo monitoruje váš systém? Třeba by jste chtěli monitorovací systém, který v případě katastrofy zašle administrátorovi SMS zprávu. Obsluha vláken. Pokud máte hodně klientů, kteří se připojují k serveru, musí mít 6

13 tento server schopnost obsloužit mnoho klientských požadavků zároveň. To znamená, že server musí být napsán jako mnohovláknový. Middleware orientovaný na zprávy. Jisté typy požadavků by měly být založeny na zprávách, kde klienti a servery jsou spojeny velmi volně (loose coupling). Potřebujete infrastrukturu, která zvládne zpracování zpráv. Životní cyklus objektu. Objekty, které žijí uvnitř serveru vyžadují, aby byly tvořeny nebo rušeny podle toho, jak se počet požadavků od klientů zvyšuje či snižuje. Sdílení zdrojů. Jestliže klient momentálně nepoužívá server, zdroje tohoto serveru mohou být vráceny do poolu, aby mohl být použit, když se připojí jiní klienti. Toto zahrnuje jak sockety (například databázová spojení) tak objekty, které žijí uvnitř serveru. Bezpečnost. Servery a databáze musejí být chráněny před narušiteli. Řádným uživatelům musí být povoleno vykonávat pouze ty operace, na které mají přidělena práva. Caching. Předpokládejme, že v databázi jsou data, která využívají všichni klienti, jako jsou například číselníky, které se mění pouze minimálně. Proč by měl váš server vyzvedávat ta samá data z databáze znovu a znovu. Často používaná data by se měla ponechávat v paměti serverů a tím se vyhnout drahému přenášení z databáze....a mnoho, mnoho, mnoho dalších. Každý z těchto problémů je separátní službou, která potřebuje být vyřešena k získání kvalitního prostředí na straně serveru. Tyto služby jsou potřeba v kterémkoliv business problému a v jakémkoliv průmyslu. A každá z těchto služeb vyžaduje hodně přemýšlení a hodně práce k jejich vyřešení. Dohromady se tyto služby nazývají middleware a při psaní business aplikací se jistě nechceme zabývat implementací těchto služeb. V dnešní době je na trhu mnoho aplikačních serverů, které tyto problémy umí řešit. Jak je ze seznamu vidět, nakoupením těchto již hotových služeb ušetříme hodně času a můžeme se věnovat implementaci business problému. 2.5 Jaké problémy chceme řešit Nastínili jsme si tedy jaké problémy se nám v zájmu zkrácení vývoje aplikace nechce řešit. Jaké tedy chceme? Představme si situaci, kdy jsme si koupili (nebo v případě open source řešení stáhli) aplikační server, který nám poskytuje dostatečné množství middleware služeb v odpovídající kvalitě. Co nám tedy zbývá? Business logika. Od dob, kdy vznikaly první osobní počítače se výrazným způsobem změnil i způsob vyvíjení nových aplikací. Bouřlivý vývoj v oblasti softwarového průmyslu s sebou přinášel mnoho změn - některé přetrvávají dodnes, některé časem zanikly. První aplikace 7

14 byly psány pouze experty z univerzit, kteří si často počítače, pro které své aplikace psali, stavěli sami. Jakmile osobní počítače přestaly být výsadou nejbohatších škol a firem a začaly pronikat do všeobecného průmyslu či domácností, vyvstal problém jak uspokojit narůstající poptávku po softwaru. Vznikalo a zanikalo mnoho metod a praktik jak co nejrychleji a co nejspolehlivěji vytvořit danou aplikaci a protože i dnes probíhají větší či menší změny v oblasti vývoje softwaru, vznikají (a zanikají) tyto metody i dnes. Přesuňme se na úroveň větší softwarové firmy, která se přirozeně v dnešním tržním prostředí snaží maximalizovat zisky a minimalizovat náklady. Takové firmě o mnoha zaměstnancích také vyvstává problém s komunikací se zákazníkem. Měl jsem tu čest pracovat ve velmi malé firmě, kde vývojový tým tvořili čtyři lidé. V takto malé firmě přirozeně platí to, že i vývojář na nejnižší pozici komunikuje se zákazníkem a řeší tzv. business problémy - tedy to co daná aplikace má vlastně řešit. Pro takového vývojáře není potom problém danou aplikaci vytvořit, protože ví jaké byly zákazníkovy zájmy - mohl s ním mluvit. Naproti tomu ve velké firmě je vývojář na nejnižší pozici od zákazníka spíše odtržen, nemá s ním kontakt a své úkoly plní ze zadání svého nadřízeného či analytika projektu. Kde je problém? V onom analytikovi. Úspěch projektu závisí na porozumění analytika zákazníkovi, jeho potřebám a přáním a také jeho schopnosti tyto požadavky správně sepsat do zadání pro vývojáře a schopnosti mu toto zadání vysvětlit. Analytik zde tedy hraje roli člověka, který předává informaci od jednoho k druhému. Často do tohoto řetězu bývá zapojeno ještě více lidí a velmi často se v tomto řetězu i nějaká ta informace ztratí. Ztráta každé byť i nepodstatné informace ovšem znamená možné předělávání projektu a tím i zvýšení nákladů, což vede ke sníženým ziskům. Komponentové technologie jsou zatím sice stále ještě mladé a současné metodiky vývoje aplikace s nimi ještě moc nepočítají, nicméně už se začínají objevovat náznaky toho, jak by v budoucnosti mohlo vypadat vytvoření aplikace. Dnes máme na jedné straně experty programátory, kteří ví jak psát v programovacím jazyce, znají všechny problémy, které to obnáší a k získání těchto znalostí studovali velmi dlouho. Jejich schopnost komunikace se zákazníkem, a to si upřímně přiznejme, je mnohdy velmi slabá. Na druhé straně zde máme analytiky, jejichž úkolem je právě komunikace se zákazníkem, chápání business problémů a průnik do nich. Přínos komponent bychom tedy mohli vidět v tom, že pokud vývojáři napíší dostatečně vhodné komponenty, ze kterých bude aplikace složena, mohou úkol poskládání aplikace, který už není tak technologicky náročný jako v případě programování, provést už analytici. Ti jsou totiž experti na business logiku a tudíž se mohou zaměřit čistě na tu. V ideálním případě tedy analytik dostane novou zakázku a protože knihovna komponent, kterou má k dispozici, je už velmi bohatá, nemusí už kontaktovat vývojáře a aplikaci poskládá z toho co má. Toto rozdělení vývoje je nesmírně důležité pro to, aby aplikace byla vytvořena rychle a co je pro úspěch projektu daleko důležitější - levně. 8

15 Nežijeme ale v ideálním světě a ani komponentové technologie nejsou onou stříbrnou kulkou (viz známý článek Freda Brookse: There is no silver bullet [BRO]), která řeší vše. K čistému rozdělení analytiků od vývojářů asi nikdy nedojde, nicméně je velmi pravděpodobné, že alespoň o pokus o zavedení podobné metodiky do firmy, přinese pozitivní výsledky. Zavedením komponentových technologií tedy chceme řešit problém rychlejšího, levnějšího a flexibilnějšího vývoje aplikací. Rozdělením zodpovědností, kdy část našich zaměstnanců se může zaměřit na technologické problémy a jiná část na business problémy, toho můžeme docílit. V následující kapitole se podívejme na to, jak by takové rozdělení zodpovědností mohlo vypadat. 2.6 Ekosystém vývoje Abyste úspěšně použili komponentové technologie, potřebujete více než aplikační server a komponenty. Vlastně se jedná o spolupráci více než šesti různých oborů, skupin - chcete-li. Každá z těchto skupin jsou experti ve svém vlastním oboru a jsou zodpovědní za klíčovou součást projektu. Protože je každá skupina specialistou, celkový čas potřebný k vytvoření aplikace enterprise třídy je podstatně snížen. Dohromady, tito hráči tvoří ekosystém vývoje. Podívejme se na to, kdo tito hráči jsou. Poskytovatel komponent Poskytovatel komponent dodává business komponenty. Tyto komponenty nejsou kompletní aplikace, ale spíše části těchto aplikací, které mohou být poskládány do jakéhosi celku. Poskytovatel komponent může být například vnitřní divize ve firmě, která dodává komponenty jiným divizím, či jeden jediný programátor. Application assember Application assembler navrhuje celkovou strukturu aplikace - je jejím architektem. Tato skupina je zodpovědná za porozumění toho, jak se dají různé komponenty kombinovat a píší aplikace, které tyto komponenty kombinují. Application assembler si může navíc některé menší komponenty napsat sám. Jeho nebo její práce je z těchto komponent postavit aplikaci, která může být nasazena s mnoha různými nastaveními. Application assembler je spotřebitel komponent, které nabízejí poskytovatelé komponent. Může vykonávat všechny nebo některé z následujících úkolů: Ze znalosti business problému rozhodovat o kombinaci existujících komponent nebo nutnosti vytvoření nových komponent, aby bylo možno nalézt efektivní řešení. Plánovat vývoj aplikace. Dodávat uživatelské prostředí. 9

16 Psát nové komponenty k vyřešení některých problémů specifických pro řešený business problém. Psát kód, který volá komponenty dodávané poskytovateli komponent. Psát integrační kód, který mapuje data mezi komponentami, které nepocházejí od jednoho poskytovatele komponent. Přeci jenom komponenty spolu nezačnou magicky pracovat hned po jejich připojení, zvláště pokud tyto komponenty napsaly různé firmy. Deployer komponent Poté co application assembler postaví aplikaci, aplikace musí být nasazena (deployment) v běžícím operačním prostředí (v aplikačním serveru). Tento úkol může čelit některým z těchto problémů: Zajištění hardwarovým nebo softwarovým firewallem a jinými ochranami. Spojení s enterprise bezpečnostními ochranami a databankami, které jsou představovány například LDAP serverem jako je Sun Java System Directory Server, Novell Directory Server nebo třeba Microsoft Active Directory. Výběr hardwaru, který bude poskytovat potřebnou úroveň kvality pro běh služby. Zajištění dalšího podpůrného hardwaru a jiných zdrojů, k poskytnutí spolehlivosti a tolerance chyb. Výkonové ladění systému. Application assembler, kterým je obyčejně vývojář nebo softwarový inženýr, není častokrát seznámen s těmito problémy. Delployeři jsou si vědomi specifických operačních požadavků a provádějí úkony zmíněné výše. Rozumí tomu, jak nasadit komponenty do aplikačního serveru a jak upravit komponenty pro specifické prostředí. Deployer má volnost přizpůsobit komponentu (někdy i server) prostředí ve kterém komponenty mají existovat. Deployer komponent může být firemní zaměstnanec, vnější konzultant nebo specializovaná firma. Administrátor systému Jakmile aplikace žije, nastupuje systémový administrátor, aby dohlížel na stabilitu řešení. Systémový administrátor je zodpovědný za funkčnost a monitorování nasazeného systému a používá k tomu runtime monitorovací a managment nástroje, které aplikační server poskytuje. Sofistikovaný aplikační server může například poslat SMS systémovému administrátorovi pokud nastane vážný problém, který vyžaduje okamžitý zásah. Některé 10

17 EJB aplikační servery tohoto dosahují provázáním s profesionálními monitorovacími produkty, jako jsou například Tivoli nebo Computer Associates. Jiné, jako například JBoss, poskytují jejich vlastní řešení systémového managementu podporou technologie Java Management Extension (JMX). Poskytovatel kontejneru a aplikačního serveru Poskytovatel kontejneru dodává komponentový kontejner (Aplikační server). To je runtime prostředí ve kterém komponenty žijí. Kontejner poskytuje komponentám middleware služby a spravuje je. V současné době existuje mnoho jednoduchých či komplexních aplikačních serverů, podporujících více různých specifikací. Nejrozšířenější a nejpopulárnější specifikaci J2EE (Java 2 Enterprise Edition specifikující komponentovou technologii Enterprise JavaBeans - EJB) podporuje okolo 20 aplikačních serverů, které mají certifikaci od firmy SUN (správce specifikace J2EE). I když se dá celý seznam těchto serverů najít na [SUN1], zmíníme zde některé populárnější: BEA WebLogic, Sun Java System Application Server, IBM WebSpehere, Oracle Application Server a zajisté také JBoss, který je vydáván pod jednou z licencí open source komunity. Poskytovatel serveru a poskytovatel kontejneru jsou jeden a ten samý. Jelikož kontejner je jednou z nejdůležitějších částí aplikačního serveru, budeme nadále rozumět kontejner = server. Poskytovatel nástrojů K usnadnění vývojového procesu komponent by měla být k dispozici standardní cesta jak postavit, spravovat a udržovat komponenty. V ekosystému komponent (zvláště pro komponenty typu EJB) existuje několik integrovaných vývojových prostředí (IDE), které vám asistují ve rychlém vývoji a lazení komponent. Některé populární proprietární nebo open-source prostředí pro Javovské typy architektur jsou například tyto: Borland JBuilder, Oracle JDeveloper, BEA WebLogic Workshop, IBM WebSphere Studio Application Developer, Sun Microsystems Java Studio, NetBeans a v neposlední řadě velmi populární Eclipse. Mnoho z těchto nástrojů vám umožňují modelovat komponenty použitím unifikovaného modelovacího jazyka (UML). Můžete v nich také generovat kód z těchto UML modelů (profesionální proprietární UML modelovací nástroje jsou například Borland Together nebo řada produktů firmy IBM Rational). Jsou zde také jiné nástroje, které budete potřebovat k rychlému a úspěšnému vývoji komponentových aplikací. Kategorie těchto produktů jsou například testovací nástroje (Junit), build nástroje (Ant či XDoclet) a tzv. profilery (Borland OptimizeIt or Quest Software JProbe), čili nástroje pro ladění výkonu softwaru. 11

18 2.7 Shrnutí rolí Obr. 2.2: Interakce mezi skupinami ekosystému Obrázek 2.2 shrnuje interakce mezi různými skupinami ekosystému. Možná se divíte proč je potřeba tolik rolí k dokončení komponentového nasazení. Odpovědí může být, že tento obor je tak rozsáhlý, že poskytuje jednotlivcům nebo společnostem příležitost stát se experty v určité roli a mohli tak poskytovat jen ty nejlepší služby. Tyto role jsou také často kombinovány dohromady. V malé nebo začínající firmě není potřeba, aby pro každou roli byl vyčleněn jeden člověk. Na místo toho je například role poskytovatel komponent, application assembler a deployer jeden a ten samý člověk. Důležité je, že je možné tyto role od sebe rozeznat a v případě potřeby je rozdělit mezi více lidí. Výčet rolí v ekosystému komponentového vývoje, jak zde byl uveden, také samozřejmě nemusí být konečný či naprosto přesný pro každou architekturu. To co zde bylo uvedeno má poskytnout přehled o tom, jaké základní role mohou existovat. 12

19 3 Komponentové modely Následující kapitola dává přehled o v minulosti či současnosti používaných komponentových modelech. Není účelem této práce poskytnout dokonalý popis každé z architektur, čili na následujících stránkách očekávejte spíše přehled těchto technologií. Zatím jsme se věnovali komponentám, které se snaží ulehčit programátorům komunikaci mezi klientem a serverem přes síť. Tyto komponentové architektury jsou typicky velmi složité a mají za úkol zjednodušovat složité struktury obrovských aplikací. Mezi tyto architektury patří například i EJB. Za komponenty by se daly považovat ale také vizuální komponenty, které mají zcela jiné určení, ale chovají se jako výše popsané komponenty, tedy jsou zapouzdřené a není je třeba před použitím výrazně upravovat. Navíc se tyto komponenty dají také skládat a kombinovat za účelem vytvoření více funkčního celku. Další skupinou, která je v poslední době velmi oblíbená a která se chová velmi podobě, jsou pluginové technologie. Plugin, v češtině nazývaný jako zásuvný modul, také funguje samostatně, zřídkakdy potřebuje ke své funkčnosti jiné pluginy a jádro aplikací, které jsou založeny na pluginech, je typicky velmi malé (veškerou funkčnost zde provádějí pluginy - jádro se tedy chová jako komponentový kontejner). V kapitolách 3.1, 3.2 a 3.3 se podíváme na typické zástupce těchto tří skupin. 3.1 EJB Enterprise Java Beans je architektura, která má za cíl usnadnit vývojářům stavbu velkých distribuovaných aplikací. Možná se pro pročtení prvních řádek manuálu k EJB může zdát, že celá věc vývoj spíše komplikuje než zjednodušuje, ale to je jenom první dojem. Tuto technologii opravdu oceníte, až když je aplikace opravdu veliká a vývoj se stává nepřehledným. EJB se snaží takový vývoj maximálně zpřehlednit. Jak už jste asi poznali z názvu, tato technologie je postavena na platformě Java, což jí dává výhodu přenositelnosti mezi operačními systémy. Enterprise beana je server-side softwarová komponenta, která může být nasazena v distribuovaném vícevrstvém prostředí. Tato komponenta se může skládat z jednoho nebo více Java objektů, protože komponenta může být víc než jen jednoduchý objekt. Bez ohledu na vnitřní kompozici komponenty přistupují klienti k jednomu jejímu veřejnému rozhraní. Toto rozhraní společně s komponentou musí splňovat požadavky, které na ně kladené EJB specifikace. Ta například vyžaduje, aby komponenta poskytovala několik přesně definovaných metod, které dovolují EJB kontejneru jednotnou správu komponent 13

20 bez ohledu na to, co komponenta dělá či pro jaký kontejner byla původně vyvíjena. To umožňuje nasadit komponentu do mnoha různých aplikačních serverů s minimálními či dokonce žádnými změnami. Protože EJB je založeno na distribuované spolupráci komponent, klientem beany může být cokoliv - servlet, applet, nebo dokonce jiná enterprise beana. V případě enterprise beany může klientský požadavek vést k volání celé řady dalších komponent. Toto je velmi silná myšlenka, protože umožňuje rozložit složitý úkol mezi komponenty tak, aby každá vyřešila jednoduchý podúkol. 3.2 Swing Swing je název jedné z architektur vizuálních komponent, které Java využívá k zobrazení GUI. Vizuální komponenta je zde zpracována jako samostatná třída, která je potomkem třídy JComponent, která představuje společný základ pro vizuální komponenty. Pokud by jste si chtěli vytvořit vlastní vizuální komponentu, stačí vaší třídu oddědit od JComponent a naimplementovat všechny abstraktní metody (jako například, jak se má komponenta vykreslovat, jak má reagovat na stisk tlačítka myši atd.). Komponenta je ve své podstatě velmi zapouzdřená a v drtivé většině se používá jako hotová třída, která se už nijak neupravuje (nedědí se z ní nové třídy). Jak ale například donutíme tlačítko, aby po jeho stisknutí vyvolalo nějakou akci, když nemůžeme komponentu tlačítka nijak upravovat? K těmto účelům máme k dispozici systém zpráv. Každá komponenta definuje seznam akcí, které je možné s ní provést a nabízí rozhraní, jehož implementací můžeme reagovat na akce, které komponenta generuje (jako je například stisk tlačítka). Swing dále nabízí speciální vizuální komponenty, které slouží pouze jako místo, kam umístit jiné vizuální komponenty - takzvané kontejnery (jako je například třída JPanel - obyčejný panel). V tomto ohledu se Swing mírně liší od jeho předchůdce AWT, na kterém je Swing založen. V AWT byl totiž rozdíl mezi kontejnerem a normální komponentou - byly to dvě různé třídy. V architektuře swing je každá komponenta zároveň kontejnerem, čili kombinování komponent do sebe je velmi jednoduché (můžeme tedy například vytvořit tlačítko, které na sobě má další tlačítko). Podobnost s principy komponentových architektur už je teď zřejmě zjevná. Máme komponenty, které jsou velmi zapouzdřené a se svým okolím komunikují pomocí zpráv, máme kontejnery, do kterých můžeme komponenty umisťovat a komponenty můžeme kombinovat do větších a složitějších celků. Ujasněme pouze, že vizuální komponenty samozřejmě nemají za úkol řešit middleware, tak jak jsme ho popsali v minulých kapitolách. 14

21 3.3 OSGi Ve světě Javy už nějakou dobu existuje vývojové prostředí Eclipse, které svými vlastnostmi a hlavně tím, že je open-source a tedy zadarmo, nalákalo mnoho uživatelů. Eclipse je ve své třetí verzi založena na technologii OSGi, která ještě více zdůrazňuje klady plugin technologie, na které je Eclipse postaven. Eclipse je vlastně jen souborem zásuvných modulů, které žijí a spolupracují okolo velmi malého jádra celé aplikace. Výhody jsou zřejmé: vývoj verzí jednotlivých pluginů lze provádět odděleně, jednotlivé součástí nebo nové pluginy lze snadno distribuovat po internetu - jsou totiž velmi malé a vzhledem k tomu, že Eclipse i OSGi jsou open-source projekty, nový plugin si může napsat úplně každý, kdo si přečte příslušné specifikace. Pluginové technologie jsou v poslední době velmi oblíbené. Možnost upravit si aplikaci dle svého je velmi lákavá. Každý má jiné potřeby a každému se také vyhovuje něco jiného. Specifikace OSGi definuje sadu rozhraní mezi jádrem a pluginy a dále definuje způsob, jakým mezi sebou komunikují jádro a pluginy nebo případně pluginy mezi dalšími pluginy. Pluginy jsou distribuovány jako.jar (java archive) soubory a k jejich použití stačí nakopírovat tento.jar soubor do adresáře plugins a Eclipse restartovat. Nic víc. Kontejner OSGi se sám postará o zkontrolování správnosti pluginu a jeho začlenění do systému. Jednoduchost nasazení (deploymentu) pluginů je jedním z faktorů, proč je tato technologie stále více oblíbenější. Řekli jsme si, že Eclipse je vlastně mnoho zásuvných modulů existujících kolem malého jádra. V analogii komponentových technologií by tedy ono jádro bylo kontejnerem, který umožňuje nahrání, život a řízení komponent a pluginy (v OSGi nazývané bundles) by byly komponenty, které poskytují veškerou funkčnost, kterou aplikace nabízí. Díky definovanému rozhraní pluginů lze tyto kombinovat do sebe, či skládat z nich větší celky. OSGi se do jisté míry také snaží řešit problematiku middlewaru. Jádro pracuje v několika vrstvách (layers), které mají za úkol řešit například problematiku bezpečnosti, služeb či životního cyklu komponenty. Detaily o specifikaci platformy OSGi jsou uvedeny v samostatné kapitole níže. 3.4 Ostatní V rychlosti se podívejme na jiné architektury, které se dnes používají. Nepovažujte následující seznam za zcela vyčerpávající: Technologie COM (Component Object Model) představuje standard firmy Microsoft pro vytváření softwarových komponent. COM komponenty (ve formě.dll a.exe souborů) nabízejí svému okolí služby skrze binárně standardizované rozhraní, čímž je dosaženo nezávislosti na implementačním programovacím jazyku. Zkratka DCOM (Distributed Component Object Model) označuje technologii COM rozšířenou o možnost 15

22 používání standardních COM komponent na vzdálených strojích. Tato technologie byla poprvé použita v osmdesátých letech při vývoji Windows a mnoho aplikací je na modelu DCOM dodnes založeno. Operační systémy firmy Microsoft od verze NT4 tuto architekturu obsahují. Microsoft dále u svého jazyka C# rozšířil možnosti dynamických knihoven (.dll), které se nyní dají úspěšně použít ve stylu komponent. Zajistil jim silný verzovací systém a maximálně zjednodušil jejich použití v IDE Microsoft Visual Studio. I u těchto.dll je poskytováno rozhraní, přes které je možné s těmito knihovnami pracovat jako s černou skříňkou (nemusíme tedy mít zdrojový kód knihovny - jsou tedy silně zapouzdřené). Common Object Request Broker Architecture je další z řady komponentových řešení, označuje se zkratkou CORBA. Tento standard vyvinula firma OMG a představuje otevřenou a nezávislou infrastrukturu, kterou aplikace používají ke spolupráci po síti. Použitím standardního protokolu IIOP (Internet Inter-ORB Protocol) může aplikace založená na architektuře CORBA, která byla vytvořena jedním výrobcem, v nějakém operačním systému, jazyku a síti spolupracovat s jinou CORBA-aplikací od stejného či jiného výrobce, běžící na jiném systému, napsanou v jiném jazyce a fungující v jiné síti. Tento model je vhodný pro mnoho situací. Protože poskytuje jednoduchý způsob jak propojit stroje od různých výrobců, s velikostí od velkých serverů, přes malé počítače a desktopy, až po hand-heldy a přenosná zařízení, vybírá si ji mnoho firem k realizaci svých enterprise řešení. Jeden z jejích nejdůležitějších a nejčastějších použití je v serverech, které musí zvládnout velký počet klientů, zasílajících mnoho požadavků a k tomu ještě s velkou spolehlivostí. Tato technologie pracuje za oponou v serverových místnostech mnoha světových webových stránek, těch, které možná používáte každý den. Není ale používána pouze pro velké aplikace; specializované verze CORBY běží na real-time systémech nebo i na přenosných zařízeních. Jak CORBA přibližně pracuje? Její aplikace jsou složeny z objektů, individuálních jednotek běžícího softwaru, které kombinují funkčnost a data a které častokrát (ale ne vždy) reprezentují něco z reálného světa. Typicky existuje mnoho instancí objektu jednoho typu - například webová stránka elektronického obchodu může mít mnoho instancí nákupního vozíku, všechny mají stejnou funkčnost, ale liší se tím, že každou vlastní jiný zákazník a obsahuje jiné zboží - to, které si zákazník zvolil k nákupu. Některé jiné typy objektů mohou mít pouze jednu instanci. Máme-li například systém pracující s bankovními účty, u kterého je použita technologie CORBY (tzn. kód je provázán s rozhraním CORBA) a je otevřen klientům na síti k použití, je obyčejně vytvořena pouze jedna instance tohoto objektu. Pro každý objektový typ, jakým by mohl být například onen nákupní košík, zadefinujete rozhraní (interface) v jazyce IDL (Interface Definition Language), dalším ze standardů firmy OMG. Přes tento interface mají klienti možnost přistupovat k objektům. Jakýkoliv klient, který chce vyvolat nějakou operaci na objektu musí použít tento interface. 16

23 Ten dokáže na straně klienta zabalit volání metody či procedury spolu s jejich argumenty a poslat toto volání přes síť. Když se volání dostane na stranu objektu (serveru), stejný interface opět dokáže volání i argumenty rozbalit a na objektu zavolat příslušnou operaci. Výsledek se poté opačnou cestou dostane zpět ke klientovi. To, že je možné se k objektu dostat pouze přes jeho interface, velmi silně zakrývá to, jak objekt operaci provádí. Jen okrajově se zmiňme o zajímavém komponentovém modelu KParts, na kterém je založen linuxový desktop KDE. Tento komponentový model byl vyvinut, protože CORBA řešení nevyhovovalo rychlostním nárokům pracovní plochy. Více informací je možné zjistit například na [KDE]. Z vědeckých aktivit můžeme připomenout projekt SOFA Karlovy Univerzity, kde se zabývají například dynamickou výměnou komponent (tzn. za běhu systému), validace komponent dle jejich chování, hierarchickými komponentami a dalšími tématy. Informace o tomto projektu naleznete na [SOFA]. 17

24 4 OSGi specifikace Tato kapitola dává zkrácený přehled komponentové architektury OSGi. Více informací může být získáno přímo ze specifikací OSGi v [OSGi1] a [OSGi2]. Open Services Gateway Initiaitve (OSGi) je nezávislá, nevýdělečná společnost vytvářející a propagující otevřené specifikace řešící služby v distribuovaných prostředích. Tyto specifikace definují OSGi Service Platform, které se skládá ze dvou částí: definice OSGi frameworku a definice množiny základních služeb. OSGi framework, který je postaven nad virtuálním strojem Javy, slouží jako běhové prostředí pro služby. Tento framework byl původně zamýšlen pro použití uvnitř embeded zařízení jako jsou set-top boxy, mobilní telefony, televize nebo třeba pračky. Nicméně časem se z něj vyvinul mocný nástroj, který je dnes například použit jako základ pro třetí verzi IDE Eclipse či se kterým se počítá při dalším vývoji frameworku Spring. 4.1 OSGi Service Platform Specifikace OSGi definuje komponentový model, který není zaměřen na řešení problematiky velkých distribuovaných aplikací, ale spíše na řešení problematiky struktury aplikace typu tlustý klient. Tato specifikace je tedy navržena pro vytváření aplikací založených na komponentách, které všechny běží uvnitř jednoho virtuálního stroje Javy. Co OSGi řeší velmi podrobně je spolupráce komponent založené na poskytování služeb a také detailní popis životních cyklů jednotlivých komponent. Specifikace OSGi frameworku je představována dvěma dokumenty: OSGi Service Platform Core Specification [OSGi1] tento dokument obsahuje specifikaci jádra implementace frameworku. Naleznete zde tedy pravidla a postupy, které musí implementace splňovat, aby v ní mohly být spouštěny komponenty napsané pro OSGi. Tvůrce komponenty pak nemusí řešit závislost na jedné konkrétní implementaci specifikace. OSGi Service Platform Service Compendium [OSGi2] tento dokument obsahuje specifikaci standardních doplňkových služeb jako je služba pro logování, či služba pro poskytnutí web serveru. V následujícím textu se budeme zabývat prvním dokumentem, protože ten definuje (pro nás zajímavý) samotný komponentový model. 18

25 Vrstvy specifikace Specifikace by se dala rozdělit do vrstev, které řeší základní požadavky na komponentový model: Vrstva komponent Zabývá se problematikou distribuce, deploymentu a validace komponent. Definuje co je komponenta a jak má být do systému začleněna. Vrstva životního cyklu komponent Definuje životní cyklus komponent. Vrstva služeb Specifikuje systém služeb poskytovaných komponentami. Vrstva komponent Fyzicky je komponenta představována jedním JAR souborem, který je jednotkou distribuce a nasazení komponenty. Tento JAR soubor obsahuje kód a zdroje (např. obrázky, knihovny atd.) spolu se souborem, který obsahuje informace o komponentě manifest. V manifestu komponenty jsou uvedeny všechny informace, které komponenta svému okolí zveřejňuje. V prostředí OSGi je totiž komponenta považována za černou skříňku, do které nemá nikdo přístup. Pokud chce komponenta někomu tento přístup poskytnout, musí tak specifikovat ve svém manifestu. Pomocí tohoto manifestu mohou tedy komponenty sdílet Java balíčky (packages), které obsahují. Framework definuje pravidla jak balíčky poskytovat (export) či možnosti jak takové poskytované balíčky využívat (import). Manifest je důležitou součástí komponenty, který kontejneru i ostatním komponentám poskytuje možnosti zjišťování informací o obsahu komponenty. Vrstva životního cyklu komponent Silnou stránkou frameworku OSGi je kontrola životního cyklu komponent. Komponenty mohou být do systému nahrávány dynamicky za běhu kontejneru, za běhu mohou být spouštěny či zastavovány a opět odinstalovávány. Komponenta se vždy nachází v jednom z definovaných stavů životního cyklu, nicméně za svůj životní cyklus se komponenta nemusí dostat nutně do všech stavů. Základními komponentami, které tvoří aplikaci v prostředí OSGi jsou ty, které mohou být nastartovány. Aby mohla být komponenta nastartována, musí v jedné ze svých tříd implementovat rozhraní BundleActivator. Toto rozhraní obsahuje metody start a stop, které framework volá pokud chce komponentu nastartovat respektive zastavit. Která třída z vnitřku komponenty toto rozhraní implementuje je definováno v manifestu komponenty. Pokud komponenta implementuje toto rozhraní je považována za výkonnou komponentu, která při svém běhu vykonává jakousi funkčnost. Na komponentu ale není kladena povinnost toto rozhraní implementovat. V 19

26 systému tedy mohou existovat komponenty, které svůj aktivátor nemají a kontejner se je tedy ani nepokouší startovat. Takové komponenty mohou být využity pouze jako nosiči typů, kteří obsahují nějakou sadu tříd či rozhraní, které exportují. Takto exportovaná rozhraní mohou být dále využita jinými komponentami. Vzhledem k tomu, že co má být exportováno je definováno v manifestu komponenty a o samotný export se postará sám framework, není v takovém případě aktivátor komponenty nutný. Framework definuje několik stavů komponenty a přechody mezi nimi: Obr. 4.1: Stavy komponenty v OSGi Popišme si ve zkratce význam jednotlivých stavů a jejich závislosti: INSTALLED komponenta je nainstalována. To znamená, že kontejner úspěšně načetl.jar soubor komponenty a zkontroloval, že komponenta je po obsahové stránce v pořádku. RESOLVED než se komponenta dostane do tohoto stavu, framework kontroluje závislosti definované v jejím manifestu tedy jestli jsou v systému přítomny všechny importované balíčky (tedy jestli pro ně existují poskytovatelé) a dále kontroluje další závislosti definované v manifestu. Tento proces se dá nejlépe přeložit jako vyhodnocení komponenty a ve specifikaci OSGi je to komplikovaný proces. Bližší informace o tomto procesu najdete v [OSGi1]. STARTING kontejner zavolal na aktivátoru komponenty metodu start a ta právě běží. Komponenta tedy startuje. V tomto stavu komponenta nejčastěji registruje či získává služby (viz níže). STARTED komponenta je úspěšně nastartována a běží. STOPPING kontejner zavolal na aktivátoru komponenty metodu stop a ta právě běží. V tomto momentě komponenta odstraňuje ze systému vše co do něj při svém 20

27 běhu zaregistrovala tak, aby po ukončení metody stop byl kontejner ve stejném stavu jako před voláním metody start. UNINSTALLED komponenta byla odinstalována z kontejneru. S takovou komponentou již nelze dále pracovat, nicméně zůstává v systému. Vrstva služeb Vrstva služeb je definována jako softwarová platforma, která podporuje komunikaci komponent na základě služeb. Tyto interakce zahrnují tři hlavní části: poskytovatelé služeb, spotřebitelé služeb a registr služeb - pouze registr služeb je považován za součást platformy. V prostředí zaměřené na služby, poskytovatelé služeb zveřejňují popis nabízených služeb a spotřebitelé služeb hledají služby, které jim vyhovují a pokud je naleznou tak se k nim připojí. Zveřejňování a hledání služeb je založeno na popisu služby manifestu. V kontextu OSGi je služba popsána jako třída Javy implementující rozhraní služby, spolu s volitelnými atributy služby, které představují dvojice klíč-hodnota. Atributy služby umožňují různým poskytovatelům služby, která má stejné rozhraní služby, aby byly mezi sebou rozlišeny. Registr služeb umožňuje spotřebitelům služeb, aby služby nacházely pomocí dotazů, formulovaných v syntaxi LDAP. Navíc je ve frameworku zaveden mechanizmus oznamování zpráv, který službám umožňuje sledovat změny, ke kterým ve frameworku dochází jako například zaregistrování nové služby, nebo odinstalování jiné. 21

28 5 CoSi Components Simplified Záměrem této diplomové práce je vytvořit takový komponentový model, který by byl maximálně jednoduchý, snadno rozšiřitelný a jednoduchý na implementaci. Jeho hlavním úkolem bude podporovat výzkum verzování a nahraditelnosti komponent. Vzhledem k tomu, že tento výzkum bude veden panem Ing. Přemyslem Bradou, Msc., Ph.D., který byl zároveň konzultantem této diplomové práce, bylo zadání této diplomové práce dáno velice přesně. Ve všech fázích vývoje specifikace i implementace byla návrhová rozhodnutí konzultována s panem Bradou a navíc základní architektura specifikace byla panem Bradou již vytvořena a mým úkolem v této práci bylo pouze doladit detaily specifikace a implementovat ji. Abych oddělil mou práci od práce pana Brady, dalo by se říci, že požadavky kladené na specifikaci v kapitole 5.1, definice základních rozhraní (Bundle, BundleContext, BundleControl, ServiceReference a ModuleClassLoader) a workflow práce kontejneru a životního cyklu komponent jsou dílem pana Brady, zbytek je dílem mým. K dispozici bylo několik technologií - komponentových návrhů - které jsou pro tento úkol využitelné. Zmínit se můžeme o technologii, nebo spíše návrhovém vzoru, IoC Inversion of Control. Tento návrhový vzor má za účel odstínit to, kde třída vezme odkazy na jiné komponenty v aplikaci, nicméně kontrola vazeb po propojení komponent je v tomto případě problematická a proto bylo nakonec od tohoto řešení upuštěno. Pro návrh CoSi modelu jsme nakonec vybrali jako vzor OSGi framework. Tento framework je velmi mocný, ale pro potřeby výzkumu verzování a nahraditelnosti komponent příliš složitý. To by ovšem šlo proti myšlence, že CoSi má být maximálně jednoduchý. Proto komponentový model OSGi sloužil pouze jako vzor zdroj inspirace kde některé věci byly zcela převzaty z tohoto frameworku, ale některé byly zcela změněny. Referenční implementace CoSi frameworku, která je také součástí této práce, se tedy nedá považovat za implementaci OSGi frameworku komponenty, které jsou napsány pro tento framework by tedy v komponentovém modelu CoSi nefungovaly. Rozdíly oproti OSGi frameworku se týkají všech věcí, které jsou z hlediska výzkumu verzování a nahraditelnosti komponent nepodstatné jako je například bezpečnost, pokročilé propojování komponent či možnost využívání nativních dynamických knihoven (*.dll, *.so). Rozdíly oproti OSGi frameworku jsou více popsány v kapitole 6.5 Rozdíly proti OSGi. Následující text se nejdříve zabývá popisem komponentového modelu CoSi kapitola 6 Specifikace CoSi. V této kapitole naleznete úplný předpis, který musí implementace splňovat, aby mohla být považována za implementaci CoSi modelu a aby 22

29 byla kompatibilní s jinými implementacemi a tedy, aby komponenty, které byly vytvořeny pro jinou implementaci, byly použitelné i v té nové. V kapitole Implementace CoSi naleznete popis referenční implementace CoSi frameworku, která je součástí této práce. Zde jsou popsány technologické detaily implementace a řešení problémů, které specifikace CoSi na implementace klade. V neposlední řadě jsou zde také popsány základní systémové služby, které byly pro tuto referenční implementaci vytvořeny. 5.1 Požadavky Návrh CoSi frameworku vychází z požadavků, které byly sepsány v analytické části vývoje specifikace. Následující seznam těchto požadavků je zajímavý nejenom z hlediska analýzy problémů, ale i z hlediska případné implementace tohoto frameworku: Plochý komponentový model Framework neumožňuje skládání komponent z jiných komponent žádná hierarchie. Všechny komponenty komunikují na stejné úrovni. Všechny komponenty mají stejný přístup ke kontejneru. Kontejner má stejný přístup ke všem komponentám. Čistý black box Vše, co komponenta poskytuje svému okolí, je specifikováno vně implementace komponenty. Pro ostatní komponenty nebo kontejner je implementace komponenty nezajímavá (a nepřístupná). Obecně maximální jednoduchost EJB verze 2/2.1jako negativní příklad složitosti. Nedá se změřit, nicméně lze například napsat krátký návod na jednu či dvě stránky, jakým způsobem vyvíjet a nasazovat komponenty do kontejneru. Potom o každé změně, která by si vynutila tento návod změnit, by muselo být uvažováno jako o změně, která zvyšuje složitost modelu. In-process Vše běží v jednom procesu v jednom virtuálním stroji. Framework neřeší žádné distribuované volání komponent. Bez dynamických aktualizací Aktualizace komponent probíhá za vypnutého stavu. To znamená, že pro aktualizaci komponent je zapotřebí tuto komponentu zastavit, poté aktualizovat a opět nastartovat. 23

30 Komunikace s (externími) klienty/uživateli přes konzoli Tento požadavek bude řešit služba konzole bude naprogramována komponenta, která bude zajišťovat službu konzole. Komunikace s (externími) klienty/uživateli přes http+html Tento požadavek bude řešit služba httpservice. Bude naprogramována komponenta realizující jednoduchý webserver bude umět obsluhovat metody GET, POST a parametry URL. Framework poskytuje StdIn/StdOut nebo HtmlIn/HtmlOut rozhraní Do implementace komponent poskytuje možnost přesměrovat vstup/výstup do zdrojů poskytovaných kontejnerem. V případě HTML komunikace poskytuje možnost přístupu ke komponentě přes URL. Možnost ovládat životní cyklus komponenty Podobný návrh jako v EJB rozhraní Home/Controller. Framework poskytuje široké možnosti jak získat informace o komponentě jejích atributech, rozhraních, vstupech/výstupech a dalších položkách, které jsou obsaženy v popisném souboru komponenty. Deklarativní propojení komponent Komponenty jsou propojeny v čase jejich instalace. Neexistuje žádná možnost jak propojit komponenty poté, co už jsou nastartovány. Komponenty jsou propojeny na základě informací, poskytnutých v popisném souboru komponenty. Kombinace Javy a Groovy Jádro kontejneru napsáno v Javě. Komponenty napsány v Groovy. Použití skriptovacího jazyka založeném na Javě dává možnost slabého typování. Možnost psaní komponent v Groovy je jedním z hlavních požadavků na framework. Možnost poskytovat více rozhraní se stejným typem jako různé služby Představte si situaci, kdy komponenta poskytuje jedno rozhraní služby, ale obsahuje dvě různé implementace tohoto rozhraní. Je zapotřebí identifikovat tyto dvě služby jako rozdílné, protože máme dvě různé implementace. Je zapotřebí poskytnout nějaký další identifikátor služby (například a:serviceinterface a b:serviceinterface ) 24

31 6 Specifikace CoSi Specifikace CoSi Components Simplified je formální specifikací pro implementaci obecně použitelného Java frameworku, jehož hlavním cílem je umožnit vývoj, běh a spolupráci samostatných a nezávislých softwarových celků, obecně nazývaných jako komponenty. Tato specifikace převážně vychází se specifikace OSGi, ze které byly některé prvky převzaty, některé upraveny a některé zcela vypuštěny (viz kapitola 6.5 Rozdíly proti OSGi ). Specifikace se skládá z popisu: komponenty tedy co to komponenta je, co obsahuje, jak jí psát a jaké má možnosti komunikace s ostatními komponentami. kontejneru kontejner je běhové prostředí pro komponenty. Je to místo, kam jsou komponenty nahrávány a kde probíhá jejich životní cyklus. V tomto kontejneru jsou k dispozici všechny dostupné informace o komponentě a zde může komponenta získávat odkazy na služby. základních služeb implementace kontejneru musí komponentám poskytovat dvě základní služby, které představují jednoduché API kontejneru v případě prvním a službu komunikace na základě událostí v případě druhém (viz níže). Předchozí tři části a celý soubor pravidel uváděný níže v textu se obecně nazývá framework. Umožňuje vytváření aplikací na základě skládání jednotlivých nezávislých komponent a poskytuje prostředky pro instalaci, provázání, spuštění a odinstalaci komponent, pokud už nejsou nadále potřebné. Použití a provázání komponent se děje dynamickým způsobem instalace komponent je možná za běhu systému, bez předchozího vypnutí, či dokonce rekompilace, celého systému. 6.1 Základní přehled Jak již bylo zmíněno aplikace založena na CoSi modelu se skládá z kontejneru a komponent, které běží ve virtuálním stroji Javy (jak je naznačeno na obrázku 6.1). Kontejner sám o sobě neposkytuje kromě podpory běhu komponent žádnou funkčnost všechna funkčnost, kterou případná aplikace poskytuje, je zajištěna jen pomocí komponent nahraných v kontejneru. 25

32 Obr. 6.1: Architektura frameworku CoSi Komponenty mohou, ale nemusí spolupracovat mezi sebou, stejně tak mohou, ale nemusí využívat služeb poskytnutých kontejnerem či základními systémovými službami. Komponentový model CoSi nemusí být nutně postaven na základech jazyka Java. Jazyk, ve kterém bude framework implementován ale musí: být objektový poskytovat možnost změny dynamického nahrávání tříd. Pro implementaci frameworku je nutné změnit způsob jak se třídy nahrávají a odkud (v Javě mechanizmus classloaderů). obsahovat mechanizmus rozhraní, které třídy implementují. Pro framework je důležitá možnost rozdělení poskytované funkčnosti a její implementace do samostatných celků (v Javě jsou to rozhraní a třídy, která tato rozhraní implementují). V následujícím textu popíšeme dva základní kameny frameworku komponentu a kontejner. Pro každou část budou definovány pravidla, které musejí splňovat. Pravidla nejsou plně omezující, to znamená, že co není zakázáno je povoleno. Nicméně co je přikázáno, musí být splněno. 6.2 Komponenta Komponenta je z hlediska CoSi modelu softwarový celek, který je uzavřen do jediného archivu, jar souboru, který obsahuje vše, co komponenta ke svému běhu potřebuje. V tomto archivu je uložen přeložený kód, všechna rozhraní a další zdroje, které 26

33 komponenta po svém spuštění využívá. Takovými zdroji mohou být multimédia, textové soubory či archivy knihoven třetích stran (jako je například log4j.jar). Platí tedy, že komponenta nemůže přímo používat nic mimo svůj archiv a naopak nikdo jiný nesmí využívat nic z vnitřku komponenty, pokud to sama nepovolí. Vnitřní implementace komponenty je před okolím skryta - to znamená, že framework, stejně jako jiné komponenty, může o komponentě zjistit co dělá, ale už je před nimi skryto jakým způsobem to dělá. Framework CoSi neumožňuje takzvané skládání komponent. Tedy techniku, při které se nová komponenta vytvoří složením několika menších komponent, a tato složená komponenta poté v systému vystupuje jako samostatný celek. Všechny komponenty v kontejneru jsou tedy jednoduchými, nehierarchickými. Archiv komponenty sice může obsahovat archivy jiných komponent, a může tedy využívat zdroje z těchto archívů, kontejner však tyto archivy považuje za obecné knihovny a nijak s nimi nepracuje Obsah komponenty V následujícím textu popíšeme co všechno může archiv komponenty obsahovat a jaké jsou možnosti komunikace s kontejnerem či s jinými komponentami. Protože komponenta je považována za černou skříňku, do které nikdo nemá implicitní přístup, musí každá komponenta obsahovat kromě přeloženého kódu a zdrojů tzv. manifest komponenty. Tento soubor má přesně danou strukturu (viz Příloha A soubor manifest.mf ) a obsahuje všechny informace o komponentně, které komponenta chce zveřejňovat. Tyto informace zahrnují kromě jména komponenty a její verze, také například závislosti na jiných komponentách, classpath komponenty atd. Kontejner tento manifest při instalaci komponenty přečte a na základě těchto metadat komponentu do systému začlení, propojí ji s jinými komponentami atd. Manifest obsahuje popis všech složek, které komponenta používá ke komunikaci s vnějším světem s kontejnerem či s jinými komponentami. Těmito složkami jsou: Aktivátor komponenty kontejner tento aktivátor používá ke spouštění či zastavování komponenty. Rozhraní a služby komponenta může poskytovat služby jiným komponentám, či tyto služby používat. Typy komponenta může svému okolí nabízet některé ze svých vnitřních tříd, či využívat třídy jiných komponent. Události kontejner poskytuje službu zajišťující příjem a doručování zpráv komponentám. Komponenty tedy v manifestu specifikují, které zprávy budou posílat, či které jsou schopny přijímat. Atributy kontejner poskytuje prostor společných atributů komponent. Komponenta 27

34 může nastavit proměnnou systému, kterou poté ostatní komponenty mohou číst. Aktivátor komponenty Každá komponenta je ve frameworku CoSi považována za spustitelnou. To znamená, že komponenta musí v jedné ze svých tříd implementovat rozhraní BundleControl (viz kapitola Rozhraní kontejneru ), které obsahuje metody start() a stop(). Každou komponentu, kterou kontejner do systému začleňuje, po instalaci také nastartuje právě pomocí těchto metod. Rozhraní BundleControl by se dalo nejlépe přirovnat k metodě main() v Javě, která slouží jako vstupní bod spuštění javovské aplikace. Stejně tak je metoda BundleControl.start() vstupním bodem pro spuštění komponenty. Která třída komponenty toto rozhraní implementuje je specifikováno v manifestu komponenty v hlavičce Control-Class. Toto je jedna z povinných hlaviček manifestu to znamená, že pokud nebude v manifestu přítomna, kontejner odmítne komponentu do systému nainstalovat. Po nastartování může komponenta chtít komunikovat s jinými komponentami v systému, vyměňovat si s nimi informace, využívat jejich funkčnosti či jim poskytovat funkčnost vlastní. To je možné několika způsoby, které si v následujících třech kapitolách popíšeme. Rozhraní (interfaces) a služby Prvním způsobem komunikace jsou služby. Služba v kontextu specifikace CoSi je ta část komponenty, která je zveřejňována okolí a jež poskytuje tomuto okolí jistou funkčnost. Systém služeb představuje dynamický model spolupráce komponent, který je úzce spjat s jejich životním cyklem. Služba je normální Java objekt, který je v systému zaregistrován pod jedním rozhraním. O správu služeb se v systému stará registr služeb. Komponenty mohou registrovat své služby do registru služeb, hledat v tomto registru služby, které chtějí použít a následně je také používat. Ve specifikaci CoSi jsou komponenty vystavěny okolo množiny spolupracujících služeb, které jsou dostupné z registru služeb. Služba je sémanticky definována jejím rozhraním a implementována jako instance služby. Rozhraní služby by mělo být specifikováno s možná co nejmenšími implementačními detaily. Framework CoSi specifikuje rozhraní základních služeb (systémová služba, služba zpráv), které mohou být komponentami využívány. Instance služby je vlastněna komponentou, která tuto službu zaregistrovala a uvnitř této komponenty také běží. Tato komponenta musí instanci služby zaregistrovat pomocí registru služeb, který je spravován kontejnerem, aby sdílení služeb mezi komponentami bylo kontrolovatelné kontejnerem. 28

35 Závislosti mezi komponentami, které poskytují službu a komponentami, které tuto službu používají jsou také spravovány kontejnerem. Například kontejner zajistí, že komponenta nemůže být zastavena, pokud se v systému nachází jiné komponenty, které využívají jejích služeb. Kontejner také zajistí, že nebude nainstalována komponenta, která ve svém manifestu specifikuje, že ke svému běhu potřebuje jistou službu, ale v kontejneru není žádná komponenta, která by tuto službu poskytovala. Framework ve svém registru služeb udržuje informace o službách a poskytuje jednoduchý, způsob jak v registru vyhledávat služby, které komponenta potřebuje. V následujícím textu prosím rozlišujte pojmy služba a instance služby. Instancí služby je myšlen již vytvořený Java objekt, který implementuje rozhraní služby a který je zaregistrován v registru služeb. Službou je myšlen celek, který obsahuje specifikaci služby (její verze, typ, atd. viz níže), rozhraní služby a také instanci služby. ServiceReference Každá služba má v registru přiřazen objekt typu ServiceReference 1. Tento objekt obsahuje vlastnosti a jiné meta-informace o službě, na kterou odkazuje, a který komponenty využívají ke zjišťování informací o zaregistrované službě či k výběru té služby, která nejvíce odpovídá jejich potřebám. Toto předchází vytváření zbytečných vazeb mezi komponentami, pokud komponenta potřebuje zjistit informace o službě, ale nepotřebuje samotnou instanci služby. Objekt typu ServiceReference může tedy být uložen a předán do komponent. Pokud se komponenta rozhodne využívat službu, na kterou se ServiceReference odkazuje, pak si o instanci služby může zažádat voláním BundleContext.getService(ServiceReference) viz vyhledávání služeb v podkapitole BundleContext kapitoly Rozhraní kontejneru. Rozhraní služby Rozhraní služby je specifikace veřejných metod služby. V praxi vývojář komponenty vytváří instance služeb z objektů, které toto rozhraní implementují a tyto objekty registruje do registru služeb. Jakmile je instance služby do kontejneru zaregistrována pod jménem rozhraní, které implementuje, může být z registru služeb získána přes toto jméno rozhraní a metody této instance jsou okolí přístupné voláním metod jejího rozhraní. Konkrétní typ instance služby je tedy skryt a komponenty využívající instanci služby znají pouze její rozhraní. Typ (myšleno fyzický) rozhraní služby tedy musí být komponentou zveřejněn, aby komponenty využívající službu mohli s touto službou pracovat. Služby, které jsou poskytovány (exportovány) musí komponenta specifikovat ve 1 Rozhraní cz.zcu.fav.kiv.cosi.servicereference 29

36 svém manifestu v hlavičce Provide-Interfaces. Služby, které naopak komponenta ke svému běhu potřebuje (jsou importovány), musí být v manifestu specifikovány v hlavičce Require-Interfaces. Detaily o těchto hlavičkách jsou uvedeny v kaptile Specifikace komponenty. Typy U komplexních služeb mnohdy nestačí pouze zveřejňovat typ rozhraní, ale je zapotřebí zveřejňovat i typy, které službu doplňují. Představme si situaci, kdy například komponenta poskytuje službu, která je schopná vybírat data z databáze. Služba obsahuje metody na zadávání dotazů do databáze a tyto metody mají speciální návratový typ, který obsahuje data z databáze. Tento typ je součástí komponenty a také součástí služby a aby mohla být služba používána, musí mít ostatní komponenty k tomuto typu přístup. Komponenta tedy ve svém manifestu specifikuje, které typy poskytuje (exportuje), či naopak které typy ke svému běhu potřebuje (importuje). Poskytované typy jsou uvedeny v hlavičce Provide-Types, zatímco importované typy jsou uvedeny v hlavičce Require- Types. Kontejner zajistí, že komponenta bude do systému nainstalována pouze v případě, kdy v systému již jsou nainstalovány komponenty, které exportují typy, které komponenta dle svého manifestu potřebuje. Události (events) Dalším typem komunikace mezi komponentami je systém událostí. Framework nabízí standardní službu MessageService (kapitola Message Service ), která se stará o přijímání a doručování událostí, neboli zpráv, komponentám. Zpráva je normální Java objekt, který dědí od abstraktní třídy Message, která je kontejnerem poskytována. Komponenta, která se systémem zpráv chce pracovat, musí tedy importovat službu MessageService a zároveň importovat typ Message. Zpráva je identifikována svým jménem a typem. Jméno zprávy je jednoduchý řetězec, který zároveň zprávu jednoduchým způsobem popisuje. Příkladem jména zprávy by byl například řetězec cosi.message.example. Typ zprávy je jméno třídy implementující abstraktní třídu Message. Zpráva také obsahuje vlastnosti je to soubor párů řetězců klíč-hodnota, který zpřesňuje informace o odesílané zprávě. Programátor zprávy může do těchto vlastností umístit libovolné informace tak, aby příjemci zprávy mohli se zprávou přesněji pracovat. K odeslání zprávy komponentou je zapotřebí v manifestu komponenty specifikovat jméno a typ odesílané zprávy (hlavička Generate-Events) a za běhu komponenty vytvořit instanci zprávy, získat instanci služby MessageService a pomocí metod MessageService.sendMessage() nebo MessageService.postMessage() zprávu odeslat. Služba se již postará o to, aby zpráva dorazila ke všem příjemcům, kteří se o odběr této zprávy přihlásili. Komponenta, která zprávu odesílá, předem neví kdo všechno zprávu 30

37 dostane to je zcela na zodpovědnosti služby MessageService. Zasílání zpráv je tedy neurčité, tzn. odesílající komponenta nemůže specifikovat konkrétní komponentu, pro kterou je zpráva určena. Pokud programátor potřebuje takový vztah mezi dvěma komponenta, měl by zvolit více popisující jméno zprávy či zvolit jiný způsob komunikace mezi komponentami například službu. Rozdíl mezi metodami sendmessage() a postmessage() je ve způsobu doručení zprávy. Metoda sendmesssage() je blokující - volání této metody neskončí, dokud odesílanou zprávu nepřijmou a nezpracují všichni příjemci. Metoda postmessage() je naproti tomu asynchronní volání této metody způsobí pouze to, že zpráva je předána službě MessageService a pak ihned dochází k návratu z metody. V druhém případě se tedy nečeká na to, až dojde ke zpracování zprávy všemi příjemci. Aby mohla komponenta zprávy přijímat, musí si do služby MessageService zaregistrovat přijímače zpráv. Přijímač je jedna třída komponenty, která implementuje rozhraní MessageConsumer poskytované kontejnerem. Tento přijímač obsahuje metodu receivemessage(message), která je službou MessageService volána při odesílání zpráv. Jaké zprávy je komponenta schopna přijímat musí specifikovat ve svém manifestu (hlavička Consume-Events). V této hlavičce se specifikuje jméno zprávy zároveň s jejím typem. Zároveň rozhraní MessageConsumer přikazuje implementovat metodu getacceptedmessages(), ve které programátor specifikuje jména zpráv, který má tento přijímač dostávat. Atributy Posledním typem výměny informací mezi komponentami jsou atributy. Atribut je libovolná hodnota, která je identifikována jednoduchým řetězcem - klíčem. Stejně jako služby nebo typy může být atribut komponentou buď poskytován (exportován) či vyžadován (importován) a stejně jako u služeb a typů kontejner zajistí, že komponenta, která vyžaduje jistý atribut, není do kontejneru nainstalována pokud v něm neexistuje žádná komponenta, která by daný atribut exportovala. Od zpráv se atributy liší v tom, že zatímco zprávy představují událost v čase, na kterou komponenty reagují, jsou atributy perzistentní hodnoty, které komponenty čtou. Atributy se dají využít k dynamické konfiguraci aplikace až za běhu systému se komponenty dovídají hodnoty z atributů a tyto hodnoty se mohou dynamicky měnit. Komponenta by se tedy neměla spoléhat na jediné přečtení hodnoty atributu, ale měla by při každé práci s atributem pokaždé ověřit, že se hodnota atributu nezměnila. Kontejner udržuje seznam všech atributů (tedy párů klíč-hodnota) a přes třídu BundleContext je nabízí k využití komponentám. Tato třída, která je předávána do aktivátoru komponenty, nabízí metody BundleContext.setAttributeValue(String, Object) a BundleContext.getAttributeValue(String). Pokud komponenta poskytuje 31

38 atribut (uvádí ho ve svém manifestu v hlavičce Provide-Attributes) má právo do atributu zapisovat nové hodnoty metodou setattributevalue(). Pokud je atribut vyžadován (je v manifestu uveden v hlavičce Require-Attributes) pak má komponenta právo tento atribut pouze číst tedy získávat jeho hodnotu metodou getattributevalue() Specifikace komponenty soubor Manifest.mf V této kapitole popíšeme obecné principy hlaviček v manifestu komponenty. Přesný syntax všech hlaviček, které framework CoSi rozpoznává, se nachází v Příloze 1 Syntax manifest.mf. Manifest komponenty se skládá z hlaviček, každá má své jméno a hodnotu, oddělené dvojtečkou. Příklad hlavičky by tedy byl: Bundle-Version: build01 Zde je tedy jménem hlavičky řetězec Bundle-Version a hodnotou je řetězec build01. V hlavičkách se často objevují definice verzí či intervalu verzí, které mají svá specifika. Zadefinujme nejdřív to, jak se v manifestu tyto dva elementy zapisují: Version Verze se skládá z hlavního, vedlejšího a doplňujícího čísla (major, minor a micro), které jsou oddělené tečkou. Volitelnou čtvrtou částí verze je popis verze (qualifier), což je textový doplněk verze, který je uveden za doplňujícím číslem, od kterého je oddělen tečkou. Verze nesmí obsahovat žádné bílé znaky, tedy mezery, tabulátory apod. Standardní hodnota pro tento výraz je Jelikož část popisu verze může obsahovat text, je při porovnávání této části použita standardní Java metoda String.compareTo() (toto například znamená, že "1.1.1.build-05" < "1.1.1.build-1" je vyhodnoceno jako pravdivé, i když intuitivně je tomu naopak). Version Range V hlavičkách týkajících se vyžadovaných typů či rozhraní se může v parametru vyskytnout interval verzí. Jestliže je výraz version-range nadefinován jako jediná verze, musí být interpretován jako rozmezí [verze, ). Pokud version-range není specifikován, je použita standardní hodnota 0. Tato hodnota se tedy namapuje na [0.0.0, ). Jelikož versionrange obsahuje čárku a tato čárka by mohla kolidovat s jinými definicemi, musí být element version-range uzavřen do uvozovek, které jakýkoliv efekt čárky ruší. Například definice vyžadovaných rozhraní: Příklady: 32

39 Příklad Predikát [1.2.3, 4.5.6) <= x < [1.2.3, 4.5.6] <= x <= (1.2.3, 4.5.6) < x < (1.2.3, 4.5.6] < x <= <= x Následují popisy jednotlivých hlaviček, které se v souboru manifest.mf mohou vyskytnout. Control-Class Tato hlavička specifikuje aktivátor komponenty. Je to jméno jedné třídy z komponenty, která implementuje rozhraní BundleControl. Tato hlavička je povinná a tedy každá komponenta, která je do kontejneru CoSi instalovatelná, obsahuje ve svém manifestu tuto hlavičku. Například: Control-Class: cz.zcu.fav.kiv.systemshell.impl.bundleactivator Bundle-Name Hlavička Bundle-Name představuje jméno komponenty. Například: Bundle-Name: com.acme.foo Bundle-Version Hlavička definuje verzi komponenty. Například: Bundle-Version: build Require-Interfaces Definice vyžadovaných rozhraní. Vývojář může specifikovat další parametry, které jsou použity při hledání vyžadovaného rozhraní. Podporovány jsou následující atributy: versionrange Rozmezí verzí, které musí mít exportované rozhraní. Syntax odpovídá výrazu version-range. Pokud atribut není specifikován, je předpokládána hodnota [0.0.0, ). name Jméno exportující služby. Pokud je v systému více služeb, které implementují stejné rozhraní, jsou mezi sebou tyto služby rozlišeny tímto jménem. bundle-name Symbolické jméno exportující komponenty. bundle-provider Jméno výrobce exportující komponenty. 33

40 bundle-versionrange Rozmezí verzí, které musí mít exportující komponenta, aby byla vybrána. Pokud atribut není specifikován, je předpokládána hodnota [0.0.0, ). Příklad správné definice: Require-Interfaces:com.acme.Foo;com.acme.Bar; versionrange="[1.23,1.24]", cz.zcu.fav.someinterface; versionrange="1.2.1"; bundle-versionrange="[1.2, 2.0)" Provide-Interfaces Definice poskytovaných rozhraní. Parametry, které mohou být specifikovány pro jednotlivá poskytovaná rozhraní. Tyto atributy mohou, ale nemusí být specifikovány. version Verze poskytovaného rozhraní. Mějte na paměti, že tato hodnota je něco jiného než verze komponenty, která tato rozhraní poskytuje. name Jméno poskytované služby. Komponenta může poskytovat více služeb se stejným rozhraním. Tyto služby jsou ve frameworku rozlišeny právě tímto jménem. Pokud je toto jméno zadefinováno, nesmí toto jméno kolidovat s jinou službou, která implementuje stejné rozhraní. Framework každému poskytovanému rozhraní automaticky přiřadí následující atributy: bundle-name Symbolické jméno komponenty, která toto rozhraní poskytuje bundle-version Verze komponenty, která poskytuje toto rozhraní. Instalace nebo update komponenty musí být přerušen, jestliže je splněna jedna z následujících podmínek: Direktiva nebo atribut je v definici vícekrát. V definici poskytovaného rozhraní je specifikován atribut bundle-name nebo bundleversion. Definice poskytovaného rozhraní automaticky neznamená, že je toto rozhraní importováno. Komponenta, která poskytuje nějaké rozhraní a zároveň toto rozhraní neimportuje, může toto rozhraní získat ze svojí classpath (definice bundle-classpath), ale ne od ostatních komponent. Příklad správné definice: Provide-Interfaces: com.acme.foo;com.acme.bar;version=1.23 Cosi-Version Verze CoSi specifikace pro kterou byla komponenta navržena. Cosi-Version ::= number 34

41 Pro tuto verzi specifikace CoSi modelu, musí být toto číslo větší nebo rovno 1. Bundle-Description Krátký popis použití a účelu komponenty. Bundle-Provider Jméno výrobce (vývojáře, dodavatele) této komponenty. Bundle-Classpath Výraz Bundle-Classpath definuje seznam *.jar souborů či adresářů uvnitř souboru komponenty, kde budou hledány zdrojové kódy, přeložené třídy či jiné zdroje potřebné pro běh komponenty. Prvky seznamu jsou odděleny čárkou. Tečka ('.') specifikuje kořenový adresář JARu komponenty. Tato tečka je také standardní hodnotou pro tuto definici (kořenový adresář je tedy vždy zahrnut do classpath). Příklad: Bundle-Classpath:., /jar/http.jar, /jar/log4j.jar Generate-Events Specifikuje události, které tato komponenta generuje. Spolu s definicí jména události (zprávy) musí také programátor specifikovat typ (třídu) zprávy. Tento typ je specifikován v povinném parametru hodnoty hlavičky type. Typ je zde uveden jeho plným jménem (tedy jméno třídy i s příslušností do balíčku). Fyzický typ události není kontejnerem automaticky exportován, programátor komponenty tedy musí tento typ explicitně exportovat v Provide-Types části manifestu. Platí tedy, že v hlavičce Generate- Event se specifikuje pouze jméno události a jméno typu, ale další metadata tohoto typu (jako je např. verze) jsou specifikovány až v Provide-Types. Parametry, které mohou být specifikovány pro událost: version Není povinný. Verze poskytované události. Pokud tento parametr není uveden, je za jeho hodnotu považována standardní hodnota 0. Consume-Events: Specifikuje události, který tato komponenta vyžaduje. Spolu s definicí jména události musí být v parametru type uveden i typ události. Typ je zde uveden jeho plným jménem (tedy jméno třídy i s příslušností do balíčku). Protože typ (třída) události je téměř 35

42 vždy nějakým speciálním typem implementovaným jinou komponentou, musí komponenta typ události importovat v Require-Types části manifestu. Při definici importované události tedy nejsou u typu uvedeny žádné doplňkové informace (jako verze, název exportující komponenty atd.) ty jsou nadefinovány v Require-Types části souboru manifest.mf. Parametry, které mohou být pro vyžadovanou událost nadefinovány: versionrange Tento parametr není povinný. Označuje rozmezí verzí importované události. Pokud tento parametr není uveden, použije se standardní hodnota [0.0.0, ). Provide-Attributes Specifikuje atributy, který tato komponenta poskytuje. Spolu s definicí jména atributu musí také programátor specifikovat v parametru type typ poskytovaného atributu. Typ je zde uveden jeho plným jménem (tedy jméno třídy i s příslušností do balíčku). Aby mohl být atribut kontejnerem správně zpracován, musí být typ atributu komponentou exportován či importován. Při definici atributu tedy nejsou u exportovaného typu uvedeny žádné doplňkové informace ty jsou nadefinovány v Provide-Types části souboru manifest.mf. Parametry, které mohou být specifikovány pro atribut: version Není povinný. Verze poskytovaného atributu. Pokud tento parametr není uveden, je za jeho hodnotu považována standardní hodnota 0. Require-Attributes Specifikuje atributy, který tato komponenta importuje. Spolu s definicí jména atributu musí být v parametru type uveden i typ atributu. Typ je zde uveden jeho plným jménem (tedy jméno třídy i s příslušností do balíčku). Aby mohl být atribut kontejnerem správně zpracován, musí být typ atributu importován (v části Require-Types). Při definici atributu tedy nejsou u importovaného typu uvedeny žádné doplňkové informace (jako verze, název exportující komponenty atd.) ty jsou nadefinovány v Require-Types části souboru manifest.mf. Parametry, které mohou být pro importovaný atribut nadefinovány: versionrange Tento parametr není povinný. Označuje rozmezí verzí importovaného atributu. Pokud tento parametr není uveden, použije se standardní hodnota [0.0.0, ). Provide-Types Zápis definice poskytovaných typů má stejný syntax jako zápis definice poskytovaných rozhraní. Rozdíl je v tom, že typy jsou třídy, které exportující komponenta 36

43 chce nabídnout jiným komponentám, ale tyto třídy nemohou být interpretovány jako služby. Pokud nějaká komponenta takový typ importuje, je tento typ přidán do classpath komponenty a ta ho tedy může používat. Require-Types Zápis definice potřebných (importovaných) typů je stejný jako zápis definice importovaných rozhraní. Rozdíl je v tom, že importované typy jsou třídy, které komponenta ke svému běhu potřebuje, nicméně tyto typy nemohou být interpretovány jako služby jiných komponent. Pokud v systému existuje komponenta, která importovaný typ poskytuje, je tento typ přidán do classpath importující komponenty. Jiná pravidla vztahující se na soubor manifestu Každá definice může být v manifest.mf vícekrát, jako platná se ale vždy bere ta poslední uvedená. Manifest může obsahovat i jiné definice než ty, které jsou zmíněny v tomto dokumentu, ale ty jsou sice načteny, ale pouze jako řetězec bez významu, který je frameworkem ignorován. Tyto definice jsou přístupné, ale nejsou nijak zpracovávány a ani nijak neovlivňují jestli bude komponenta nainstalována či ne Distribuční forma komponenty Komponenta musí být distribuována jako jediný *.jar (JavaArchive) soubor, který obsahuje vše potřebné pro běh komponenty. Framework uzavírá komponentu do jejího *.jar souboru a nedovoluje jí využívat zdroje odjinud. Uvnitř archívu komponenty je povinný adresář META-INF, ve kterém je uložen povinný soubor manifest.mf, který obsahuje meta-informace o komponentě. Název adresáře i souboru musí být přesně tak, jak je uvedeno v tomto dokumentu. Archiv musí obsahovat další povinné adresáře, tak jak je uvedeno níže. Kontejner při instalaci komponenty kontroluje přítomnost těchto povinných adresářů a pokud v archivu nejsou nalezeny, instalace končí chybou a komponenta není do systému zavedena. Uvedeny jsou také nepovinné adresáře, které jsou zde uvedeny proto, aby se zavedla jistá konvence pojmenování adresářů. Těmito adresáři jsou (na obrázku 6.2 jsou povinné položky odlišeny tmavší barvou): 37

44 Obr. 6.2.: Struktura Adresář bin/ - povinný adresář, který obsahuje přeložený kód komponenty. Tento adresář je standardně zahrnut do classpath komponenty a programátor komponenty tedy tento adresář do classpath přidávat nemusí. Adresář lib/ Povinný adresář, který obsahuje knihovny potřebné pro běh komponenty. Tyto knihovny mohou být v archivu uloženy jako *.jar archivy (viz níže). Pokud komponenta ke svému běhu žádné knihovny nepotřebuje, může tento adresář být prázdný, nicméně musí být stále přítomen. Knihovny, které chce komponenta využít musí být uvedeny v classpath komponenty v jejím manifestu. Adresář optional/ nepovinný adresář, který může obsahovat v podstatě cokoliv. archivu komponenty Adresář src/ Adresář obsahující zdrojové kódy komponenty, pokud je dodavatel chce poskytnout. Adresář doc/ Nepovinný adresář obsahující dokumentaci komponenty. Aby byla distribuce komponent ulehčena, poskytuje framework možnost načítání zdrojů z jarů uvnitř jaru (standardní implementace Javy toto neumožňuje). Toto vnořování jarů lze ale použít pouze pro jednu úroveň. Představme si tedy, že komponenta je například distribuovaná v souboru Komponenta.jar. Tento archiv obsahuje třídy a zdroje (obrázky, data) potřebné pro běh komponenty a může také obsahovat jiný archiv se zdrojovými kódy (například systém logování log4j.jar). Jednou úrovní vnořování archívů je myšleno to, že archiv log4j.jar uvnitř komponenty Komponenta.jar už nemůže obsahovat další jar archivy. 6.3 Kontejner Kontejner je část jádra modelu CoSi, který je zodpovědný za: korektní nahrávání komponent do systému a obstarávání jejich životního cyklu (kapitola 6.3.1) udržování registru služeb poskytovaných komponentami (kapitola 6.3.4) udržování seznamu a hodnot atributů poskytovaných komponentami (kapitola 6.3.4) poskytování informací o komponentách jejich stavu, závislostech, metadat a dalších (kapitola 6.4.1) 38

45 poskytování služby, přes které je možné ovládat životní cyklus komponent (kapitola 6.4.1) poskytování služby, kterou komponenta může využít k posílání či přijímání zpráv (viz kapitola Message Service ) Kontejner je služba na pozadí, která sama o sobě nenese žádnou funkčnost, ale pouze poskytuje prostředí pro běh komponent, podobně jako operační systém poskytuje prostředí pro vývoj a běh spustitelných programů Životní cyklus komponenty Životním cyklem je míněn proces od počátku existence komponenty v systému do jejího odstranění ze systému. Komponenta v tomto procesu nabývá několika stavů, které v této kapitole popíšeme. Aby mohla být komponenta v systému použita, musí být nejdříve nainstalována tedy nahrána do systému. Poté dochází k ověření jejích závislostí s ostatními komponentami a k ověření korektnosti komponenty. Tento proces se nazývá vyhodnocení komponenty. Jakmile je komponenta vyhodnocena, nebrání již nic tomu, aby byla komponenta spuštěna a tedy aby mohla zahájit svoji činnost uvnitř systému. Není-li komponenta nadále žádána, je možné její běh zastavit a případně tuto komponentu se systému zcela odinstalovat. Komponenta může tedy nabývat jednoho z následujících stavů: INSTALLED komponenta byla úspěšně nainstalována RESOLVED komponenta je vyhodnocena všechny komponentou vyžadované závislosti jsou v systému přítomny. Tento stav vyjadřuje, že komponenta je buď připravena na nastartování nebo byla zastavena. STARTING komponenta je startována. Na komponentě byla zavolána metoda BundleControl.start() a volání této metody ještě nebylo ukončeno. STARTED komponenta byla úspěšně nastartována a ta nyní běží. STOPPING komponenta je ukončována. Na komponentě byla zavolána metoda BundleControl.stop() a tato metoda ještě neskončila. UNINSTALLED komponenta byla odinstalována. Nemůže být přesunuta do jiného stavu. 39

46 Obr. 6.3: Stavový diagram komponenty Aktivním stavem komponenty je v textu myšleno to, že se komponenta nachází v jednom ze stavů STARTING, STARTED nebo STOPPING. Instalace komponent Aby bylo možné komponentu do systému nainstalovat musí splňovat všechny požadavky, které jsou na na komponentu kladené. Kontejner v průběhu instalace komponenty: 1. přiřadí komponentě jednoznačný identifikátor číslo, které se v průběhu životního cyklu komponenty nebude měnit (ani při aktualizaci) 2. vytvoří pro tuto komponentu classloader (viz kapitola ClassLoader Architektura ), 3. ověří že archiv komponenty obsahuje všechny potřebné adresáře 4. nahraje metadata komponenty ze souboru manifest.mf a ověří, že tyto metadata jsou validní (obsahují všechny nutné hlavičky) 5. zkontroluje, zda jsou v archivu komponenty fyzicky přítomny všechny typy a rozhraní, které jsou dle manifestu poskytovány. Komponenta nemusí obsahovat ta rozhraní, které sama importuje. Toto je motivováno situací, kdy chce komponenta poskytovat službu, ale typ rozhraní této služby je poskytován jinou komponentou. 6. zkontroluje, zda je v archivu přítomna třída aktivátoru komponenty Pokud komponenta úspěšně projde všemi těmito testy, je možné jí přesunout do 40

47 stavu INSTALLED tedy do stavu, který označuje že komponenta je validní a může být vyhodnocena. Kontejner poskytuje systémovou službu, která umožňuje instalaci komponent. Detaily o podobě této služby hledejte v kapitole System Service Vyhodnocování komponent V procesu vyhodnocování komponent kontejner ověřuje závislosti komponenty, které jsou specifikování v jejím manifestu. Pokud se komponenta nachází ve stavu RESOLVED, tedy vyhodnocená, znamená to, že podmínky v kontejneru komponentě vyhovují a tato tedy může být nastartována. Více o procesu vyhodnocení v kapitole o procesu vyhodnocování komponent níže. Startování komponent Každá komponenta musí v jedné ze svých tříd implementovat interface BundleControl, který obsahuje metodu start(bundlecontext). Pomocí této třídy kontejner startuje komponentu, která se musí nejdříve nacházet ve vyhodnoceném stavu. Znamená to tedy, že komponenta může být nastartována až poté, co k tomu má podmínky v kontejneru. Těsně před voláním metody start() je stav komponenty nastaven na STARTING a tento stav je zachován až do úspěšného ukončení volání této metody. V průběhu startování může komponenta registrovat služby, získávat odkazy na služby či pracovat s atributy kontejneru. Do metody start je předáván objekt BundleContext, který komponenta k těmto operacím využívá. Pokud start komponenty proběhl bez chyb, je stav komponenty nastaven na STARTED a tato je tedy považována za běžící. Více detailů o způsobu zpracování startování komponent kontejnerem je popsáno v kapitole popisující rozhraní BundleControl. Zastavování komponent Pokud je komponenta ve stavu STARTED je možné jí zastavit voláním BundleControl.stop(). Podobně jako u startování komponent kontejner nabízí ve své systémové službě (SystemService) operaci, která umožňuje zastavovat komponenty. Těsně před voláním metody stop() musí být komponenta přesunuta do stavu STOPPING a v tomto stavu musí setrvat až do návratu z volání ukončovací metody. Pokud komponenta A poskytuje rozhraní má tedy v kontejneru zaregistrované své vlastní služby a v kontejneru se nachází komponenta B, která tato rozhraní importuje, musí být komponenta B nejdříve zastavena a odinstalována, aby mohla být zastavena komponenta A. Toto omezení je v návrhu proto, aby se zajistilo správně běhové prostředí pro komponenty. Na rozdíl od modelu OSGi neexistují v CoSi žádné generátory zpráv, které by komponentám oznamovaly, že určitá služba byla ze systému odstraněna. Pokud 41

48 tedy komponenta běží, je jí zaručeno, že všechny služby, na které při svém běhu získala odkaz budou v systému přítomny až do doby, kdy je na komponentě zavolána metoda stop(). Aktualizace komponent Kontejner ve své systémové službě poskytuje operaci, kterou lze použít pro aktualizaci (update) komponent. Proces aktualizace podporuje přesun z jedné verze komponenty na novější verzi stejné komponenty za běhu systému. Aktualizace se od prostého odinstalování komponenty a opětovného nainstalování jiné verze komponenty liší tím, že komponentě zůstává stejný jednoznačný identifikátor, který od kontejneru obdržela při instalaci. Deinstalace komponent Systémová služba nabízí operaci uninstall(), kterou komponenty používají k odinstalování jiných komponent. Odinstalována může komponenta, která je ve stavu RESOLVED, čili ta, která byla nejdříve zastavena. Pokud komponenta A poskytuje typy, atributy nebo zprávy a v kontejneru se nachází komponenta B, která jeden z těchto elementů využívá tedy je importuje -, musí být komponenta B nejdříve zastavena a odinstalována, aby mohla být odinstalována komponenta A. Toto omezení je v návrhu proto, aby se zajistilo správně běhové prostředí pro komponenty podobně jako je u tomu v případě zastavování běžících komponent a služeb. Předtím než je komponenta přesunuta do stavu UNINSTALLED, musí framework zajistit odstranění všech stop komponenty v systému jak je to jen možné. V ideálním případě je po návratu z metody uninstall() kontejner ve stavu, v jakém by byl, kdyby komponenta v systému nikdy nainstalována nebyla ClassLoader architektura Mnoho komponent obecně sdílí jeden virtuální stroj (VM). Uvnitř tohoto virtuálního stroje, mohou komponenty skrývat rozhraní, typy a další soubory (dohromady nazývané jako zdroje) před ostatními komponentami, ale též mohou tyto zdroje s ostatními komponentami sdílet. Hlavním mechanizmem tohoto skrývání a sdílení zdrojů je použití systému classloaderů 2 Javy. ClassLoader je v Javě třída, která je zodpovědná za nahrávání ostatních tříd ze souborů do paměti. Zjednodušeně se dá říci, že classloaderu je předán název 2 Český překlad - nahrávač tříd je v tomto případě trochu krkolomný, zůstaňme tedy radši u anglického výrazu. 42

49 souboru s třídou, která má být do paměti nahrána. Classloader je poté zodpovědný za natáhnutí dat do paměti a jejich interpretaci jako třídy Javy. V případě CoSi frameworku musí být použit speciální classloader, který bude dodržovat pravidla definovaná níže. Každá komponenta má svůj vlastní classloader, který se stará o nahrávání zdrojů této komponenty do systému. Aby mohly komponenty mezi sebou sdílet zdroje, je potřeba vytvořit síť propojených classloaderů, které si mezi sebou poskytují zdroje podle přesně daných pravidel. Classloader komponenty může nahrávat své zdroje z těchto lokací: Boot classpath ClassPath, která je dostupná pro každou komponentu bez rozdílu. Jedná se o základní zdroje, které jsou potřeba k napsání programu v Javě. Jedná se tedy o všechny třídy ze základních balíčků Javy a protože komponenta může být napsána v jazyce Groovy, jsou také automaticky poskytovány zdroje ze základních balíků jazyka Groovy. Konkrétně se jedná o tyto balíčky: sun.*; com.sun.*; cz.zcu.fav.kiv.cosi.*; groovy.*; org.codehaus.groovy.* Je důležité, aby tyto základní zdroje poskytoval framework a to jedině on. Komponenta může předpokládat, že tyto zdroje jsou k dispozici a tyto zdroje si do své classpath nesmí přidávat. V případě, že by si totiž každá komponenta tyto základní zdroje nahrávala sama, docházelo by výjimkám přetypování. Vezměme si jako příklad třídu java.lang.integer - i když by byl soubor v jedné komponentě totožný se souborem též třídy v jiné komponentě, skutečnost, že tu samou třídu nahrály dva různé classloadery, by Java interpretovala jako dvě různé třídy. Framework classpath Framework obyčejně poskytuje základní sadu rozhraní či typů, které jsou potřeba k výrobě komponent. Jedná se například o rozhraní BundleContext a BundleControl. Tyto základní typy a rozhraní, framework automaticky přidává do classpath komponenty. Tyto třídy tedy nemusí komponenta importovat jsou importovány automaticky. Bundle classpath V manifestu komponenty (soubor manifest.mf) si komponenta může nadefinovat vlastní classpath. Tato classpath je relevantní pouze pro vnitřek komponenty. Tedy může se odkazovat pouze na adresáře či archivy uvnitř archivu komponenty. Prostor tříd komponenty jsou poté všechny třídy, které jsou dosažitelné pro classloader dané komponenty. Prostor tříd tedy obsahuje třídy z: Rodičovského classloaderu (obyčejně třídy z boot classpath a framework classpath) Importovaná rozhraní Importované typy 43

50 Vlastní classpath komponenty Jak již bylo zmíněno, prostor tříd musí být konzistentní to znamená, že nikdy nesmí obsahovat dvě třídy se stejným úplně kvalifikovaným jménem. Nicméně pokud jsou dva prostory tříd odděleny, mohou každý obsahovat třídu se stejným úplně kvalifikovaným jménem. Implementace kontejneru tedy musí obsahovat implementaci classloaderu, který je schopný dodržovat výše uvedená pravidla. Součástí specifikace je definice rozhraní ModuleClassLoader, které je základním rozhraním pro každý takový classloader. Další detaily například o algoritmu nahrání třídy do paměti hledejte v samostatné kapitole pro toto rozhraní Rozhraní kontejneru, podkapitola Rozhraní ModuleClassLoader Proces vyhodnocení komponenty V průběhu instalace komponenty je tato komponenta nejdříve vyhodnocena (v angl. jazyce označováno jako bundle resolve). Vyhodnocení komponenty je proces, ve kterém se pro jednotlivé importy komponenty (tedy import rozhraní, typů, atributů a zpráv) hledají odpovídající poskytovatelé. Komponenty na své importy mohou ukládat omezení, například ve formě specifické verze rozhraní, či přesného názvu komponenty, která by měla rozhraní poskytovat. Přesný popis možných omezení hledejte v kapitole Specifikace komponenty. Pokud není nalezena žádná komponenta, která by poskytovala žádaný zdroj, proces vyhodnocení skončí s chybou a komponenta není korektně vyhodnocena (to znamená, že nemůže být spuštěna). Komponenta v systému zůstává, ale je zpět v instalovaném stavu (stav INSTALLED). Je tedy možno se o vyhodnocení komponenty pokusit znovu později, za jiných podmínek. Proces vyhodnocení musí být proveden ještě předtím, než z komponenty nahrán či spuštěn jakýkoliv kód. V průběhu vyhodnocování kontejner kontroluje: 1. zda se komponenta nachází v INSTALLED či RESOLVED stavu. Komponenta tedy musí být korektně nainstalována, aby mohla být vyhodnocena. Je možné znovu vyhodnotit již vyhodnocenou komponentu. 2. zda se v systému nacházejí poskytovatelé pro všechny importovaná rozhraní. Jde pouze o ověření přítomnosti těchto poskytovatelů, v tomto momentě se tedy nevytvářejí žádné vazby na tyto poskytovatele. 3. zda se v systému nacházejí poskytovatelé pro všechny vyžadované typy. Stejně jako u rozhraní jde pouze o ověření přítomnosti takových poskytovatelů. 4. zda se v systému nacházejí poskytovatelé pro všechny vyžadované atributy. Stejně jako u rozhraní jde pouze o ověření přítomnosti takových poskytovatelů. 5. zda se v systému nacházejí poskytovatelé pro všechny vyžadované zprávy. Stejně 44

51 jako u rozhraní jde pouze o ověření přítomnosti takových poskytovatelů. 6. zda typy u poskytovaných atributů jsou komponentou fyzicky exportovány. Tedy jestli kromě poskytovaného atributu je také poskytována třída atributu. Toto pravidlo může být porušeno v případě, že typ atributu je komponentou importován pak typ atributu nemusí být uveden v Provide-Types části manifestu. Toto je vhodné v případě, že komponenta chce poskytovat atribut, ale typ (třída) tohoto atributu jí není fyzicky dostupný jinak, než importem z jiné komponenty. Komponenta přirozeně nemusí exportovat typy, které jsou součástí Boot class path viz kapitola ClassLoader architektura. 7. zda typy poskytovaných zpráv jsou komponentou fyzicky exportovány. Pro zprávy v tomto případě platí stejná pravidla jako u atributů (bod 6.) 8. Pokud byla komponenta před vyhodnocením ve stavu RESOLVED je v tomto momentě proces vyhodnocení ukončen. Jestliže všechny předchozí kroky proběhly úspěšně je komponenta ponechána ve stavu RESOLVED. Pokud alespoň jeden z předchozích kroků selhal je komponenta přesunuta do stavu INSTALLED a všechny následující kroky musí být znegovány tedy kontejner se musí vrátit do stavu, v jakém byl před prvním (úspěšném) vyhodnocením této komponenty. Pokud byla komponenta ve stavu INSTALLED, proces pokračuje dalšími kroky normálně. 9. Do kontejneru jsou zaregistrovány všechny zdroje (rozhraní, typy, atributy či zprávy), které komponenta poskytuje, tak aby ostatní komponenty měly k těmto zdrojům přístup přes delegaci nahrávání tříd (viz kapitola ClassLoader architektura). 10. Dojde k navázání komponenty na své poskytovatele. K tomuto účelu neexistuje v CoSi žádný speciální objekt (wire), čili navázání může být implementováno pouhým seznamem, kdo co exportuje či importuje. 11. Vytvoří se instance aktivátoru komponenty třídy, která je v manifestu uvedena pod hlavičkou Bundle-Control. Pokud se všechny uvedené kroky povede úspěšně provést je komponenta přesunuta do stavu RESOLVED a je tedy připravena ke spuštění. Při ověřování poskytovatelů rozhraní, typů, atributů či zpráv musí být brán zřetel na případné verzování či jinou specifikaci jednotlivých zdrojů tak, aby komponenta byla propojena se správným poskytovatelem. Více o problematice omezení (constraints) viz kapitola Specifikace komponenty Rozhraní kontejneru I když je komponenta považována za černou skříňku tedy filozofie je taková, že okolí neví o komponentě nic, kromě toho co poskytuje a co potřebuje ke svému běhu, je 45

52 zapotřebí, aby komponenta měla možnost určitým způsobem komunikovat s frameworkem a aby framework mohl komunikovat s komponentou. Framework proto poskytuje dvě rozhraní, která toto zajišťují. Jedná se o rozhraní BundleControl, které má komponenta za povinnost implementovat v jedné ze svých tříd a tuto třídu uvést v manifestu v definici Control-Class. Skrz toto rozhraní má framework možnost řídit životní cyklus komponenty. Druhým rozhraním, které je frameworkem poskytováno, je interface BundleContext. Toto rozhraní poskytuje komponentě základní informace o jejím okolí. Více v příslušné kapitole níže: Rozhraní BundleControl BundleControl je rozhraním, které musí být implementováno jednou třídou komponenty, aby kontejner mohl komponentu spouštět a zastavovat. Při vyhodnocování (resolve) komponenty kontejner vytvoří instanci třídy, která je uvedena v manifestu komponenty pod hlavičkou Control-Class a ověří, že tato třída tento interface skutečně implementuje. Pokud se na této instanci zdaří úspěšně zavolat metodu start() je zaručeno, že při ukončování běhu komponenty se metoda stop() zavolá na stejné instanci BundleControl. Třída, která v komponentě implementuje rozhraní BundleControl, musí mít veřejný konstruktor bez parametrů, aby bylo možné instanci třídy vytvořit pomocí Class.newInstance(). Těsně před voláním metody start() je komponenta přesunuta do stavu STARTING a v tomto stavu přetrvává až do úspěšného ukončení volání této metody. Nedojde-li v průběhu volání start() k žádným problémům, je komponenta přesunuta do stavu STARTED a považuje se za úspěšně běžící. Analogicky, těsně před voláním metody stop() je komponenta přesunuta do stavu STOPPING a v tomto stavu přetrvává až do doby, kdy je volání metody stop() ukončeno. V takovém případě se stav komponenty vrací na RESOLVED. Kontejner zajistí bezpečné spuštění obou dvou operací. Jakákoliv chyba či výjimka, která nastane v průběhu spouštění či ukončování běhu komponenty, musí být odchycena tak, aby kontejner či ostatní komponenty nebyly tímto chybovým spuštěním ovlivněny. Pravidla pro chybová volání operací jsou tyto: Pro metodu start(): Výjimku, kterou metoda start() vygenerovala musí kontejner zalogovat Kontejner se musí vrátit do stavu před voláním metody start(). Pokud tedy komponenta stihla před vyvoláním výjimky zaregistrovat některé služby či atributy, musí být tyto kontejnerem odstraněny. Komponenta se vrátí do stavu RESOLVED. Pro metodu stop(): 46

53 Výjimku, kterou metoda stop() vygenerovala musí kontejner zalogovat Je velmi pravděpodobné, že komponenta nestihla odregistrovat všechny služby či atributy, které při svém běhu mohla zaregistrovat. Je tedy nutné, aby kontejner odstranil všechny služby či atributy, které komponenta registrovala. Komponenta se vrátí do stavu RESOLVED. Metoda start je místem, kde by komponenta měla získat odkazy na jiné služby, či zaregistrovat své vlastní služby a atributy. Získání či registrace je možné přes rozhraní BundleContext, které je v metodě poskytnuto jako vstupní parametr. Framework zajistí, že metoda bude zavolána pouze jednou při startování komponenty a zatímco je komponenta aktivní (tedy v jednom ze stavů STARTING, STARTED a STOPPING) bude jakékoliv volání této metody blokováno tedy pokus o nastartování již nastartované komponenty selže. Pokud byla komponenta dříve zastavena (metodou stop()) je možné její opětovné spuštění. Metoda stop() je místem, kde komponenta musí zrušit registrace všech svých zaregistrovaných služeb, atributů či zpráv. Metoda stop() je volána se stejnou instancí BundleContext jako při volání metody start(), komponenta tedy není nucena ukládat si odkaz na BundleContext lokálně. Interface BundleControl je definován takto: public interface BundleControl { public void start(bundlecontext P_bd); public void stop(bundlecontext P_bd); } Rozhraní BundleContext Kontext komponenty uvnitř frameworku. Kontext komponenta využívá ke komunikaci a přístupu do frameworku a k přístupu ke službám, které jsou ve frameworku zaregistrovány. Skrz tento objekt může komponenta registrovat své služby a také získávat reference na služby ostatní. Kromě těchto funkcí poskytuje BundleContext komponentě další funkčnost: Registrovat čí získávat služby (viz níže) Získat metadata komponenty Využívat standardní vstup a standardní výstup poskytovaný frameworkem Zapisovat nebo číst atributy (viz níže) 47

54 Instance BundleContext je vytvářena při startu komponenty a je komponentě předávána při volání metody BundleControl.start(BundleContext). Stejná instance této třídy je předávána komponentě asociované s tímto kontextem také při volání metody BundleControl.stop(BundleContext) tedy při ukončování běhu komponenty. Tento kontext je obecně považován za těsnou součást komponenty a měl by být využíván pouze asociovanou komponentou. Sdílení kontextu s jinými komponentami v CoSi frameworku je tedy považováno za nevhodné využití tohoto objektu. Instance kontextu je platná pouze během aktivního stavu komponenty tedy pouze v době, kdy je komponenta ve stavu STARTING, STARTED nebo STOPPING 3. Pokud komponenta není v jednom z těchto stavů, nesmí se instance kontextu již nadále využívat. Při opětovném spuštění komponenty je vytvořena nová instance kontextu, kterou je možné opět využít. Framework je jediná entita, která může vytvořit instanci třídy BundleContext a tyto instance jsou platné pouze ve frameworku, který je vytvořil. Registrace a získávání služeb Komponenta může registrovat nebo získávat pouze ty instance služeb, které uvedla ve svém manifestu v definicích Require-Interfaces či Provide-Interfaces. Pokud se komponenta pokusí zaregistrovat službu, která v manifestu nebyla uvedena v části Provide- Interfaces, provedou se následující operace: 1. Framework zapíše takový pokus do logu tedy pouze oznámí chybu 2. Služba nebude zaregistrována 3. Běh komponenty nebude ovlivněn framework nebude generovat výjimku Pokud se komponenta pokusí získat instanci služby, která nebyla uvedena v manifestu v části Require-Interfaces, provedou se následující operace: 1. Framework zapíše takový pokus do logu tedy pouze oznámí chybu 2. Místo instance služby se vrátí null 3. Běh komponenty nebude nijak jinak ovlivněn - framework nebude generovat výjimku Ke každé službě, kterou komponenta chce do kontejneru zaregistrovat, může být připojena sada vlastností (properties), které danou službu dále popisují. Jedná se o sadu párů klíč-hodnota, obojí typu String. V dalším textu jsou tyto vlastnosti označovány jako vlastnosti služby. Tyto vlastnosti jsou vhodné v případě, kdy programátor služby očekává, že v 3 Tedy v překladu startuje, běží a ukončuje se 48

55 systému bude v budoucnu více instancí stejné služby. Kontejner totiž umožňuje pro jedno rozhraní registrovat neomezené množství instancí služeb. Pro ostatní komponenty může tedy být obtížné vybrat tu, která by jim vyhovovala nejlépe. Informace uvedené ve vlastnostech služby pomáhají komponentám ve výběru konkrétní instance služby. Tyto informace jsou zcela dynamické. Znamená to tedy, že klíče vlastností, které budou ke službám připojovány, nejsou uvedeny v manifest.mf a je zcela na vůli programátora komponenty, jaké informace do vlastností služby uvede. Naopak při získávání instancí služeb je možné, kromě třídy služby, také specifikovat podobnou sadu vlastností. Kontejner se poté postará o to, aby byla vrácena instance té služby, která odpovídá žádaným vlastnostem. Kontejner porovnává každou položku žádaných vlastností s položkami vlastností registrovaných služeb a když najde shodu, vrátí komponentě nalezenou službu. Nazvěme vlastnosti specifikované při registraci služby registrovanými vlastnostmi a vlastnosti, které jsou specifikovány při získávání instance služby žádanými vlastnostmi. Algoritmus shody vlastností je poté následující: 1. Pokud je v žádaných vlastnostech určitý klíč, musí tento klíč být také v registrovaných vlastnostech a hodnoty obou klíčů musí být stejné. 2. Pokud je v registrovaných vlastnostech klíč, který se v žádaných vlastnostech nevyskytuje, je tento ignorován. Kdybychom chtěli tyto pravidla popsat ještě jinak, mohli bychom říci, že žádané vlastnosti musí být podmnožinou registrovaných vlastností, aby mohlo dojít ke shodě. Programátor komponenty ovšem může využít i metod, které vlastnosti služeb zcela ignorují, přesněji řečeno registrují nebo získávají služby s prázdnou sadou vlastností. V případě získávání instancí je poté nespecifikováno, která z množiny služeb bude komponentě vrácena. Jedná se o metody registerservice(string, Object) a getservice(string), viz níže. Posledním způsobem jak pracovat s informacemi o službě při získávání instance služby je metoda getservicereferences(string, HashMap<String, String>). Tato metoda vrací seznam všech služeb, které vyhovují danému typu (první argument), a jejichž registrované vlastnosti vyhovují žádaným vlastnostem (druhý argument). Tato metoda tedy nevrací rovnou instanci první vyhovující služby, jak je tomu u metody getservice(string, HashMap<String, String>), ale odkazy na všechny služby, které vyhovují. Tyto odkazy (ServiceReference) lze využít pro získání dodatečných informací o službě, či pro získání instance služby. Komponentě je povoleno získat odkazy na jakékoliv služby v systému. Pro získání odkazu, a tedy informací o službě, nemusí tato služba být uvedena v manifestu komponenty. Použití atributů 49

56 Komponenta musí všechny atributy, které chce ve svém běhu využít, uvést v souboru manifest.mf. Pravidla pro používání atributů jsou o něco komplikovanější, než je tomu u služeb. Pokud je atribut uveden v Require-Attributes části souboru manifest.mf (komponenta daný atribut importuje), potom je komponentě dovoleno takový atribut pouze číst tedy získat jeho hodnotu. Pokud má atribut nějaký speciální typ, který není poskytován kontejnerem 4, musí být typ tohoto atributu uveden v Require-Types části souboru manifest.mf. Komponenta tedy musí příslušný typ atributu importovat. Pokud je atribut uveden v Provide-Attributes části souboru manifest.mf (komponenta daný atribut poskytuje), potom je komponentě dovoleno takový atribut číst i zapisovat tedy provádět na něm všechny operace. V případě, že atribut je speciálního typu, musí být tento typ uveden buď v Provide-Types nebo Require-Types části souboru manifest.mf. Volně přeloženo to znamená, že komponenta musí daný typ atributu buď poskytovat ostatním komponentám, nebo tento typ musí sama importovat. To je vhodné v situaci, kdy komponenta chce poskytovat jistý atribut, nicméně sama musí typ tohoto atributu importovat, protože tento typ jí není jiným způsobem dostupný. Rozhraní BundleContext je definováno takto: public class BundleContext { public void registerservice(string clazz, Object service); public void registerservice ( String clazz, Object service, HashMap<String, String> P_properties); public void unregisterservice(object service); public Object getservice(string clazz); public Object getservice(string Ps_clazz, HashMap<String, String> P_properties); public Object getservice(servicereference P_reference); public ServiceReference[] getservicereferences(string clazz, HashMap<String, String> P_properties); public InputStream getstdin(); public OutputStream getstdout(); public void setattributevalue(string Ps_attributeName, Object P_attributeValue); public Object getattributevalue(string Ps_attributeName); public BundleMetadata getbundlemetadata(); } Popis jednotlivých metod: public void registerservice(string Ps_clazz, Object P_service); Zaregistruje instanci služby P_service do kontejneru. Služba bude v kontejneru 4 Frameworkem jsou automaticky poskytovány typy z balíčků java.*, groovy.* a další. Viz kapitola ClassLoader architektura. 50

57 vedena pod názvem Ps_class, což je také plně kvalifikované jméno typu služby. Typ argumentu P_service se musí s tímto názvem shodovat. V průběhu registrace služby se vytvoří objekt typu ServiceReference, který bude přiřazen registrované instanci služby a který bude ostatním komponentám dostupný přes volání metody getservicereferences, viz níže. Při registraci se také provede ověření, že komponenta má povoleno daný typ služby registrovat, to znamená, že je tento typ uveden v manifestu komponenty pod hlavičkou Provide-Interfaces. Služba se zaregistruje s prázdnými vlastnostmi (properties). public void registerservice ( String clazz, Object service, HashMap<String, String> P_properties); Tato metoda má stejné použití i chování jako metoda registerservice(string, Object) až na to, že je zde možné specifikovat vlastnosti služby. Argument P_properties nesmí být null. public void unregisterservice(object service); Odstraní registraci služby z kontejneru. Metodě je předávána instance stejného objektu, který byl předán při registraci služby. Poté co byla služba z kontejneru odstraněna, již není ostatním komponentám přístupná. public Object getservice(string Ps_clazz); Tato metoda vrátí instanci služby, která je v kontejneru zaregistrována pod typem Ps_clazz a jejíž typ (tzn. název typu, verze typu atd.) odpovídá tomu, co je uvedeno v manifestu komponenty pod hlavičkou Require-Interfaces. Pokud je v kontejneru více služeb, které vyhovují těmto podmínkám, je nedefinováno, která z těchto služeb je vrácena. Pokud se komponenta pokusí získat instanci služby, na kterou nemá právo, musí tento pokus skončit s chybou. Tato metoda také ignoruje vlastnosti služeb, které tedy při výběru instance služby nehrají žádnou roli. public Object getservice(string Ps_clazz, HashMap<String, String> P_properties); Tato metoda má stejné použití i chování jako metoda getservice(string) až na to, že je zde možné specifikovat vlastnosti služby. Argument P_properties nesmí tedy být null a v tom případě je vrácena instance první služby, která vyhovuje podmínkám vyžadovaných vlastností. public Object getservice(servicereference P_reference); Metoda vrátí instanci služby na základě reference na službu. 51

58 public ServiceReference[] getservicereferences(string clazz, HashMap<String, String> P_properties); Metoda vrátí seznam referencí na služby na základě jména služby (první argument) a vyžadovaných vlastností (druhý argument). Při výběru služeb se postupuje stejným způsobem jako v případě metody getservice(string, HashMap<String, String>) s tím rozdílem, že metoda nevrací instanci první vyhovující služby, ale vrátí seznam všech služeb, které daným kritériím vyhovují. public InputStream getstdin(); Metoda vrátí proud (stream) standardního vstupu, poskytovaného kontejnerem. public OutputStream getstdout(); Metoda vrátí proud (stream) standardního výstupu, poskytovaného kontejnerem. public void setattributevalue(string Ps_attributeName, Object P_attributeValue); Touto metodou je možné nastavit systémový atribut. Aby mohla komponenta nastavovat atributy, je musí být tento atribut komponentou poskytován, to znamená, že musí být uveden v manifestu pod hlavičkou Provide-Attributes. public Object getattributevalue(string Ps_attributeName); Metoda vrací hodnotu systémového atributu. Aby mohla komponenta číst hodnoty atributů, musí mít tyto atributy uvedeny v jejím manifestu pod hlavičkami Require- Attributes nebo Provide-Attributes. public BundleMetadata getbundlemetadata(); Tato metoda poskytuje komponentě možnost přístupu k jejímu vlastnímu manifestu. Rozhraní Bundle Objekty typu Bundle je abstrakcí komponenty uvnitř kontejneru. Každá nainstalovaná komponenta má v kontejneru přiřazen právě jeden objekt tohoto typu. Jediným kdo je oprávněn vytvářet tyto objekty je kontejner sám. Rozhraní je definováno takto: public interface Bundle { public static final int INSTALLED = 0; public static final int RESOLVED = 1; public static final int UNINSTALLED = 2; public static final int STARTING = 3; public static final int STARTED = 4; public static final int STOPPING = 5; 52

59 } public String getbundlelocation(); public boolean installbundle(); public boolean uninstallbundle(); public boolean resolvebundle(); public void startbundle(); public boolean stopbundle(); public void updatebundle(url Ps_newBundleUrl); public boolean isinstalled(); public boolean isresolved(); public boolean isstarted(); public boolean isactive(); public int getstate(); public BundleMetadata getbundlemetadata(); public int getid(); void setid(int Pi_id); public String getname(); Popis jednotlivých složek rozhraní: Konstanty INSTALLED, RESOLVED, UNINSTALLED, STARTING, STARTED a STOPPING představují jednotlivé stavy komponenty. Význam stavů je popsán v kapitole o životním cyklu komponent. public boolean installbundle(); public void uninstallbundle(); public boolean resolvebundle(); public void startbundle(); public boolean stopbundle(); public void updatebundle(url Ps_newBundleUrl); Tyto metody kontrolují životní cyklus komponenty a jsou také popsány v kapitole o životním cyklu komponent. public String getbundlelocation(); Vrátí cestu uvnitř souborového systému k archivu komponenty. public boolean isinstalled(); public boolean isresolved(); public boolean isstarted(); Tyto metody vrátí true pokud se komponenta nachází v příslušných stavech. public boolean isactive(); Metoda vrátí true pokud se komponenta nachází v jednom ze stavů STARTING, STARTED nebo STOPPING. public int getstate(); Vrátí stav komponenty. Číslo výsledku odpovídá konstantám pro stavy 53

60 definovaným v tomto rozhraní. public BundleMetadata getbundlemetadata(); Vrátí zpracovaná metadata komponenty. public int getid(); Vrátí jednoznačný identifikátor komponenty uvnitř kontejneru. void setid(int Pi_id); Nastaví jednoznačný identifikátor komponenty. public String getname(); Vrátí jméno komponenty obvykle jméno archivu komponenty. Rozhraní ServiceReference Tento objekt obsahuje informace o vlastnostech služby registrované v kontejneru. Mezi tyto informace patří například jméno rozhraní, které služba implementuje, metadata služby (informace poskytnuté v souboru manifest.mf) či vlastnosti instance služby. Tento objekt může být používán jinými komponentami k výběru instance služby. Představme si situaci, kdy je v kontejneru zaregistrováno více služeb, které implementují stejné rozhraní. Protože ke každé instanci služby, která je v kontejneru zaregistrována, je přiřazen seznam vlastností (property set), může si komponenta, která o instanci služby žádá, na základě tohoto dodatečného seznamu vlastností mezi instancemi služeb vybírat tu, která ji vyhovuje nejvíce. K tomuto účelu komponenty používají metodu getservicereferences(). Tyto dodatečné vlastnosti nejsou specifikovány v souboru manifest.mf komponenty a je tedy zcela na vůli programátora komponenty/služby, jaké vlastnosti instanci služby při její registraci přiřadí. Rozhraní je definováno takto: public interface ServiceReference { public String getclazz(); public int getid(); public void setid(int id); public Object getservice(); public Bundle getprovidingbundle(); public HashMap<String, String> getproperties(); } Popis jednotlivých metod rozhraní: 54

61 public String getclazz(); Vrátí plně kvalifikované jméno typu rozhraní, které tato služba implementuje. public int getid(); Vrátí jednoznačný identifikátor služby uvnitř kontejneru. public void setid(int id); Nastaví jednoznačný identifikátor služby uvnitř kontejneru. public Object getservice(); Vrátí instanci služby. Jméno typu služby odpovídá tomu co vrací metoda getclazz(). public Bundle getprovidingbundle(); Vrátí odkaz na komponentu, která tuto službu poskytuje. Je to komponenta, která pro registraci služby volala metodu BundleContext.registerService(). public HashMap<String, String> getproperties(); Vrátí seznam vlastností instance služby. Rozhraní ModuleClassLoader Obecné rozhraní pro ClassLoader, který je použitelný v CoSi kontejneru. Implementace tohoto rozhraní odpovídá CoSi pouze pokud dodržuje následující pravidla: ClassPath classloaderu musí být dynamická. To znamená, že classloader podporuje dynamickou změnu classpath za běhu systému přidávání nebo odebírání položek classpath. To je v kontrastu se základním classloaderem Javy, který tohoto není schopen. ClassPath classloaderu se vztahuje pouze na položky uvnitř distribučního archivu komponenty. Všechny cesty uvedené v classpath komponenty jsou tedy relativní ke kořenu stromu archivu komponenty. Musí udržovat seznam tříd, které se nebude pokoušet nahrát se svých vlastních zdrojů, ale bude o ně žádat classloadery jiných komponent. Je to seznam importovaných typů/rozhraní komponenty. Musí být velmi opatrný pokud chce cachovat zdroje. Při implementaci musí mít vývojář stále na paměti, že komponenty mohou být aktualizovány a že kód z classpath 55

62 komponenty, který byl již jednou do paměti nahrán, se může za běhu změnit. Metoda loadclass(), tedy samotné nahrání třídy do paměti musí mít následující algoritmus: 1. Nejdříve zkontrolovat cache classloaderu, jestli tato třída již nebyla dříve nahrána. Toto je krok, který classloader musí provést, protože v celém virtuálním stroji musí být pouze jedna jediná instance objektu typu Class, který obaluje nahraný kód třídy. Virtuální stroj Javy totiž při porovnávání typů používá referenci na Class objekt porovnávaných typů a typy jsou shodné pouze pokud mají shodnou referenci na svůj Class objekt. Pokud by jste bytekód jedné třídy nahráli ze souboru dvakrát, měli by jste dva Class objekty (s jinými referencemi) a Java by velmi pravděpodobně padala na výjimky ClassCastException, i když je bytekód stejný. Takže vracejte pouze jedinou instanci objektu Class pro jednotlivou třídu pro každé volání metody loadclass() 2. Jestliže třída pochází z balíčku java.*, deleguj nahrání třídy rodičovskému classloaderu. 3. Jestliže třída pochází z jednoho z balíčků, které jsou uvedeny v seznamu boot delegation, pak deleguj nahrání třídy rodičovskému classloaderu. 4. Jestliže je třída uvedena v seznamu importovaných tříd/rozhraní, deleguj nahrání třídy classloaderu, který uvedenou třídu/rozhraní exportuje. 5. Konečně, pokud nic z předchozího nevedlo k nahrání třídy, pokus se nahrát třídu z vlastní classpath. 56

63 Grafické znázornění předchozího algoritmu: Obr. 6.4: Algoritmus nahrání třídy do paměti Classloader musí být schopen nahrávání zdrojů, které jsou obsaženy ve vnořených archivech (nested jar). Ve standardních implementacích classloaderů, které jsou poskytovány Javou, není možné umístit archiv.jar do jiného archivu.jar a od classloaderu požadovat zdroje, které jsou obsaženy ve vnořeném jaru. Model CoSi vyžaduje po classloaderu, aby toto možné bylo. Vzhledem k tomu, že prostor classpath komponenty je omezen pouze na položky uvnitř distribučního archivu, musí programátor komponenty do archivu umístit všechny zdroje, které komponenta přímo potřebuje ke svému běhu. Mezi těmito zdroji mohou být i knihovny třetích stran. Díky schopnosti classloaderu číst vnořené archivy, muže tedy programátor umisťovat tyto knihovny například do adresáře lib/ distribučního archivu a uvést je do classpath komponenty. Tyto archivy pak budou komponentou používány tak, jako kdyby byly mimo jar komponenty. Rozhraní je definováno takto: public interface ModuleClassLoader { public Class loadclass(string Ps_className) throws ClassNotFoundException; public URL getresource(string P_resource); public void addtoclasspath(string P_classPath) throws MalformedURLException; 57

64 } public void addclasstodelegate(string Ps_classname); Popis jednotlivých metod: public Class loadclass(string Ps_className) throws ClassNotFoundException; Nahraje třídu ze zdrojového souboru na základě plně kvalifikovaného jména třídy. Algoritmus nahrání třídy se řídí pravidly popsanými výše. public URL getresource(string P_resource); Vrátí URL ke zdroji. Zdrojem muže být jakýkoliv soubor, který se nachází uvnitř classpath. Metoda akceptuje plnou cestu k souboru. public void addtoclasspath(string P_classPath) throws MalformedURLException; Přidá novou cestu do dynamicky zpracovávané classpath. public void addclasstodelegate(string Ps_classname); Metoda akceptuje plně kvalifikované jméno třídy, kterou přidá do seznamu tříd k delegaci seznamu importovaných typů. Viz výše. BundleMetadata V balíčku cz.zcu.fav.kiv.cosi.bundlemetadata je k dispozici sada tříd, které mají za úkol ulehčit práci s metadaty komponenty. Tyto třídy dohromady tvoří parser, který je schopný zpracovat soubory manifest.mf tak, jak jsou definované v tomto dokumentu. Pro detailní popis tříd z tohoto balíčku prosím konzultujte javadoc dokumentaci k tomuto balíčku a přílohu A syntax souboru manifest.mf. 6.4 Základní služby Kontejner poskytuje komponentám základní API ve formě dvou služeb: SystemService je systémová služba, kterou komponenty využívají ke kontrole životních cyklů jiných komponent a ke zjišťování informací o vnitřním stavu kontejneru. MessageService je systémová služba, kterou komponenty mohou využít ke zasílání či přijímání zpráv, pokud tyto závislosti definovaly ve svém manifestu. 58

65 Tyto dvě služby jsou komponentám k dispozici vždy. Znamená to tedy, že kontejner musí tyto dvě služby spustit co nejdříve po svém startu a vždy před nainstalováním či spuštěním jiných komponent. Pro každou službu kontejner vytvoří speciální pseudokomponentu jejíž jediným úkolem bude poskytovat danou službu. Slovem pseudokomponenta je myšleno to, že implementace nemusí nutně vycházet z klasické komponenty, nicméně pro ostatní komponenty bude v systému viditelná komponenta systembunde poskytující službu SystemService a komponenta messagebundle poskytující službu MessageService. Ostatní komponenty mohou s těmito dvěma systémovými komponentami pracovat tak, jako kdyby to byly komponenty obyčejné až na to, že kontejner nepovolí jejich zastavení. Je pravidlem, že služba SystemService je nainstalována a nastartována jako první a služba MessageService jako druhá System Service Implementace frameworku musí obsahovat komponentu, která při svém nastartování zaregistruje do systému službu SystemService. Tato služba poskytuje ostatním komponentám základní přístup do vnitřku systému. Rozhraní této služby je součástí frameworku a nachází se v balíčku cz.zcu.fav.kiv.cosi.messageservice. Využitím metod v této službě mohou ostatní komponenty instalovat jiné komponenty a provádět na nich operace životního cyklu. Služba také obsahuje metody poskytující informace o dynamickém stavu kontejneru tedy jaké komponenty jsou v kontejneru nainstalovány, informace o závislostech mezi komponentami (kdo poskytuje/vyžaduje jaké rozhraní, typ, atribut či událost) atd. Implementace této služby má obecně jen malou přidanou funkcionalitu a je spíše myšleno jako delegátor volání požadavků do jádra kontejneru. Instance této služby je v kontejneru vždy přítomna jako služba s id 0 a je nastartování předtím, než jsou do kontejneru nainstalovány či spuštěny jiné komponenty. Komponenty nemají právo k zastavování systémové služby. Rozhraní služby je definováno takto: public interface SystemService { public HashMap<Integer, Bundle> getbundles(); public Bundle getbundle(int Pi_id); public Version getcontainerversion(); public void shutdowncontainer(); //životní cyklus komponent public void installbundle(string Ps_bundleId); public void uninstallbundle(int Pi_id); public void startbundle(int Pi_id); public void stopbundle(int Pi_id); public void updatebundle(int Pi_id, String Ps_newBundleURL); //informace o stavu komponenty 59

66 public Collection<ProvidingTypeHeaderEntry> getexportedtypesforbundle(int Pi_id); public Collection<RequiringTypeHeaderEntry> getimportedtypesforbundle(int Pi_id); public Collection<ProvidingTypeHeaderEntry> getexportedinterfacesforbundle(int Pi_id); public Collection<RequiringTypeHeaderEntry> getimportedinterfacesforbundle(int Pi_id); public Collection<NamedProvidingTypeHeaderEntry> getprovidedattributesforbundle(int Pi_id); public Collection<NamedRequiringTypeHeaderEntry> getconsumedattributesforbundle(int Pi_id); public Collection<NamedProvidingTypeHeaderEntry> getprovidedmessagesforbundle(int Pi_id); public Collection<NamedRequiringTypeHeaderEntry> getconsumedmessagesforbundle(int Pi_id); public Collection<ServiceReference> getinstalledservicesforbundle(int Pi_id); } Popis jednotlivých metod rozhraní: public HashMap<Integer, Bundle> getbundles(); Vrátí mapu všech komponent nainstalovaných v kontejneru nezávisle na stavu komponenty. Klíčem mapy je jednoznačný identifikátor komponenty a hodnotou je komponenta sama. public Bundle getbundle(int Pi_id); Vrátí referenci na komponentu na základě jejího jednoznačného identifikátoru. Pokud komponenta s tímto číslem v systému neexistuje, služba zaloguje chybu a vrátí null. public Version getcontainerversion(); Vrátí číslo verze kontejneru. Pro návratovou hodnotu se použije typ z balíčku cz.zcu.fav.kiv.cosi.bundlemetadata. public void shutdowncontainer(); Ukončí běh kontejneru a celého programu. V průběhu ukončování jsou postupně zastaveny a odinstalovány všechny nainstalované komponenty a to od té nejpozději nainstalované až k té nejdříve nainstalované. Zjednodušeně se dá říci, že první bude zastavena služba s nejvyšším ID a jako poslední bude zastavena služba SystemService, která má ID 0. public void installbundle(string Ps_bundleId); public void uninstallbundle(int Pi_id); public void startbundle(int Pi_id); public void stopbundle(int Pi_id); public void updatebundle(int Pi_id, String Ps_newBundleURL); Tyto metody delegují volání operací životního cyklu na komponentu s příslušným 60

67 Id. Pro detaily o životním cyklu komponenty jsou uvedeny v kapitole Životní cyklus komponenty. public Collection<ProvidingTypeHeaderEntry> getexportedtypesforbundle(int Pi_id); Vrátí seznam typů, které poskytuje komponenta se specifikovaným ID. public Collection<RequiringTypeHeaderEntry> getimportedtypesforbundle(int Pi_id); Vrátí seznam typů, které vyžaduje komponenta se specifikovaným ID. public Collection<ProvidingTypeHeaderEntry> getexportedinterfacesforbundle(int Pi_id); Vrátí seznam rozhraní, které poskytuje komponenta se specifikovaným ID. public Collection<RequiringTypeHeaderEntry> getimportedinterfacesforbundle(int Pi_id); Vrátí seznam rozhraní, které vyžaduje komponenta se specifikovaným ID. public Collection<ProvidingNamedTypeHeaderEntry> getprovidedattributesforbundle(int Pi_id); Vrátí seznam atributů, které poskytuje komponenta se specifikovaným ID. public Collection<RequiringNamedTypeHeaderEntry> getconsumedattributesforbundle(int Pi_id); Vrátí seznam atributů, které vyžaduje komponenta se specifikovaným ID. public Collection<ProvidingNamedTypeHeaderEntry> getprovidedmessagesforbundle(int Pi_id); Vrátí seznam událostí, které poskytuje komponenta se specifikovaným ID. public Collection<RequiringNamedTypeHeaderEntry> getconsumedmessagesforbundle(int Pi_id); Vrátí seznam událostí, které vyžaduje komponenta se specifikovaným ID. public Collection<ServiceReference> getinstalledservicesforbundle(int Pi_id); Vrátí seznam služeb, které do kontejneru zaregistrovala komponenta se specifikovaným ID Message Service Implementace frameworku musí obsahovat komponentu, která při svém nastartování zaregistruje do systému službu MessageService. Tato služba poskytuje ostatním komponentám možnost zasílání či přijímání zpráv (událostí). Komponenty 61

68 využívají typy Message, MessageService a MessageConsumer k vytváření zpráv, jejich zasílání či přijímání. Pokud chce komponenta generovat novou událost, implementuje k tomuto účelu abstraktní třídu Message, která představuje abstrakci události použitelné v prostředí CoSi. Takto vytvořený objekt poté zašle do služby pomocí metod sendmessage() nebo postmesage(), které volá na rozhraní služby. Tato služba se poté postará o doručení zprávy všem komponentám, které jsou přijetí takovéto zprávy schopny. Komponenta, která chce přijímat zprávy - tedy naslouchat událostem - musí v jedné ze svých tříd implementovat rozhraní MessageConsumer. Tento objekt je poté zaregistrován do služby MessageService pomocí metody registermessageconsumer(). Služba doručuje zprávy tomuto objektu ke zpracování. Služba se postará o kontrolu toho, že komponenta, která zprávu odesílá či přijímá, má na takovou akci právo. To znamená, že informace o událostech uvedené v manifestu komponenty musí souhlasit s tím, co se komponenta pokouší odesílat či přijímat. Služba tedy povolí odeslat pouze ty zprávy, které jsou v manifestu uvedeny v hlavičce Generate- Events a dále povolí přijmout pouze ty zprávy, které jsou v manifestu uvedeny v hlavičce Consume-Events. Před doručením zprávy také musí implementace služby zkontrolovat, že komponenta, do které se zpráva odesílá, je stále v aktivním stavu. Pokud ano, pak se zpráva doručí normálně. Pokud však již komponenta v aktivním stavu není, musí být se služby odebrány všechny implementace rozhraní MessageConsumer, které tato komponenta registrovala, a těmto přijímačům se již nesmí doručovat žádné zprávy. Tato podmínka je zde z důvodu možného nepovedeného ukončení běhu komponenty - při ukončování komponenty by tato měla odregistrovat všechny přijímače, které registrovala. Pokud při ukončování dojde k výjimce a v důsledku toho se nestihnou odregistrovat všechny přijímače, či pokud na to programátor prostě zapomene, musí to za něj udělat služba MessageService ověřením aktivního stavu komponenty. Instance této služby je v kontejneru vždy přítomna jako služba s id 1 a je nastartována ihned poté co je nastartována služba SystemService a předtím, než jsou do kontejneru nainstalovány či spuštěny jiné komponenty. Ostatní komponenty, kromě služby SystemService, nemají právo k zastavování této služby. Rozhraní MessageService Základní rozhraní služby umožňující zasílání zpráv a registraci příjemců zpráv. Toto rozhraní je definováno takto: public interface MessageService { public void registermessageconsumer(messageconsumer P_consumer, Bundle P_consumingBunde); 62

69 } public void unregistermessageconsumer(messageconsumer P_consumer); public void sendmessage(message P_message); public void postmessage(message P_message); Popis jednotlivých metod: public void registermessageconsumer(messageconsumer P_consumer, Bundle P_consumingBunde); Zaregistruje nového přijímače zpráv, tedy objekt, který je schopen přijímat zprávy. Spolu s tímto objektem je do služby předáván odkaz na instanci Bundle komponenty, která se k odebírání zpráv přihlašuje. Tento objekt může komponenta získat přes její BundleContext. Služba na základě tohoto kontextu ověří, že komponenta má právo k odebírání zpráv, které MessageConsumer definuje. public void unregistermessageconsumer(messageconsumer P_consumer); Odstraní registraci příjemce zpráv. Po ukončení této metody už této instanci typu MessageConsumer nejsou doručovány žádné zprávy. public void sendmessage(message P_message); Pošle zprávu všem příjemcům zpráv, kteří jsou schopni tuto zprávu přijmout. Tato metoda doručí zprávu synchronně, to znamená, že volání této metody je blokující až do doby, než ukončí zpracování zprávy poslední příjemce. Součástí zprávy je i informace o komponentě, která zprávu zaslala. Implementace služby se postará o zkontrolování toho, jestli komponenta, která zprávu posílá má právo takovou zprávu odeslat tedy jestli je tato zpráva uvedena v jejím manifestu. Doručování zpráv by mělo být ošetřeno proti špatně napsaným přijímačům tak, aby případná výjimka neovlivnila běh služby, či doručení zprávy ostatním přijímačům. public void postmessage(message P_message); Pošle zprávu všem příjemcům zpráv, kteří jsou schopni tuto zprávu přijmout. Tato metoda doručuje zprávy asynchronně, to znamená, že volání této metody je neblokující a tedy dochází k návratu z metody ihned poté, co je službě MessageService předána informace o takové zprávě. Služba se nezávisle na volajícím (tzn. v jiném vlákně) postará o doručení zprávy všem příjemcům. Součástí zprávy je i informace o komponentě, která zprávu zaslala. Implementace služby se postará o zkontrolování toho, jestli komponenta, která zprávu posílá má právo takovou zprávu odeslat tedy jestli je tato zpráva uvedena v jejím manifestu. Doručování zpráv by mělo být ošetřeno proti špatně napsaným přijímačům tak, aby případná výjimka neovlivnila běh služby, či doručení zprávy ostatním přijímačům. 63

70 Abstraktní typ Message Abstraktní třída události pro službu MessageService. Zpráva se skládá ze tří částí, které ji jednoznačně identifikují. Jméno zprávy řetězec, který představuje krátký popis zprávy. Obyčejně se skládá z několika slov oddělených tečkou. Například cosi.logging.enabled. Obsah zprávy Vlastnosti zprávy Obsahuje seznam párů řetězců klíč-hodnota, které zpřesňují informace o zprávě. Některé informace jsou nastaveny službou, další může specifikovat zasilatel zprávy. Kromě těchto vlastností obsahuje tento typ také informaci o tom, která komponenta tuto zprávu zaslala (metoda getsendingbundle()). Všechny implementace tohoto typu si musí dávat pozor na to, aby si zachovávaly status Serializable. Tato třída má jediný veřejný konstruktor, do kterého se předává instance typu Bundle. Je to odkaz na komponentu, která tuto zprávu odesílá. Abstraktní implementace rozhraní MessageConsumer Framework nabízí jednoduchou implementaci rozhraní MessageConsumer pro pohodlnější práci se službou MessageService. Tato implementace nese jméno cz.zcu.fav.kiv.messageservice.abstractsimpleconsumer a z rozhraní implementuje pouze metodu getacceptedmessages(). Metoda vrací jména všech zpráv, které komponenta definovala ve svém manifestu v hlavičce Consume-Events. Přijímače, které budou dědit od této abstraktní implementace budou tedy reagovat na všechny zprávy, na které má komponenta právo a budou muset implementovat pouze metodu receivemessage(). 6.5 Rozdíly proti OSGi Ačkoliv specifikace CoSi velmi silně vychází z frameworku OSGi, jsou zde jisté (mnohdy velmi zásadní) rozdíly. V této kapitole ve zkratce tyto rozdíly popíšeme. Spíše než detailním popisem toho, jak je ta či ta věc řešena ve frameworku OSGi a jaké důvody autory tohoto frameworku k těmto řešením vedly, chápejte tuto kapitolu spíše jako výčet rozdílů. Detailní popis frameworku OSGi najdete v [OSGi1]. Export/Import typů Nejzásadnějším rozdílem mezi oběma specifikacemi je způsob jakým komponenty sdílejí své zdroje, tedy co komponenty exportují či importují. 64

71 V OSGi řešeno na úrovni balíčků. V manifestu se tedy specifikuje jaký balíček z vnitřku komponenty má být poskytnut okolí, či jaký balíček je komponentou vyžadován. V CoSi řešeno na úrovni tříd. V manifestu se specifikuje jméno konkrétní třídy která má být exportována či importována a tento export/import může být verzován (viz parametry Provide-Types, Provide-Interfaces, Require-Types, Require-Interfaces). Toto designové rozhodnutí nám poskytlo větší kontrolu nad tím, co komponenta vlastně exportuje či importuje. Hledání závislostí mezi komponentami je tak snazší a a vazby jsou pevnější. Nevýhodou je, že pokud například komponenta exportuje padesát tříd z jediného balíčku, musí být do manifestu všechny tyto třídy vypsány. V OSGi by na to stačil jediný řádek. Bezpečnost CoSi framework neřeší ani nepředpisuje jakoukoliv úroveň zabezpečení systému. V OSGi existuje mechanizmus validace komponent, i když je tento mechanizmus volitelný a tedy nemusí být implementován. K ověřováni komponent je v OSGi možno použít certifikátů, různých klíčů atd. V CoSi jsme se rozhodli bezpečnost neřešit, protože z hlediska výzkumu verzování a nahraditelnosti komponent je to nezajímavá funkčnost. Zjednodušená ClassLoader architektura Ve frameworku OSGi je práce s classloadery mnohem složitější. To je dáno především tím, že export/import pracuje na základě balíčků a také například tím, že framework definuje takzvané fragmenty, tedy neúplné komponenty, či možnost dynamických importů ty které jsou vyhodnocovány až za běhu. Groovy To co framework OSGi nepodporuje a co CoSi specifikace přináší zcela nové je možnost psát komponenty v dynamicky typovaném, plně interpretovaném jazyku Groovy. CoSi classloaderům předepisuje možnost nahrávat zdrojové kódy napsané v tomto jazyku a pracovat s nimi jako s normálními Java soubory. Navíc musí být takový classloader schopen zároveň zpracovávat i komponenty napsané celé v čisté Javě. Nativní knihovny Framwork CoSi nepodporuje práci s nativními knihovnami (.dll,.so), OSGi framework ano. 65

72 Běhové prostředí Framework OSGi specifikuje jako jednu položku manifestu konfiguraci běhového prostředí (execution environment), které musí být splněno, aby mohla být komponenta nainstalována. V takové konfiguraci se například specifikuje, že komponenta vyžaduje Javu verzi 1.5 či minimální verzi specifikace OSGi, kterou kontejner musí implementovat. Nic takového v CoSi není. Manifest a struktura komponenty Manifest a struktura komponenty se v obou frameworcích liší. Zatímco struktura (adresáře) komponent jsou si velmi podobné, položky manifestu jsou zcela jiné. Kromě toho, že názvy jednotlivých hlaviček jsou jiné, jsou jiné i jejich významy. Perzistence stavu kontejneru OSGi framework nakazuje implementacím kontejneru, aby při ukončení frameworku sice zastavili a odinstalovali všechny komponenty, nicméně pokud byla komponenta aktivní, musí si kontejner toto zapamatovat a při příštím startu kontejneru musí všechny dříve aktivní komponenty nainstalovat a spustit. Nic takového v CoSi není zde se při ukončení kontejneru zastaví a odinstalují všechny komponenty, ale při příštím startu se začíná s čistým štítem. Povinnost implementovat BundleControl Ve frameworku CoSi má komponenta povinnost implementovat aktivátor komponenty BundleControl. V prostředí OSGi komponenta tuto povinnost nemá. 66

73 7 Implementace CoSi Nedílnou a významnou součástí této diplomové práce je konkrétní implementace kontejneru specifikace CoSi. V této poslední části práce popíši architekturu implementace a popíši doplňkové komponenty a služby, které byly vytvořeny jednak pro snazší používání této implementace, ale také jako ukázkové komponenty, které programátoři mohou použít jako vzory pro vytváření budoucích komponent. Jelikož tato implementace CoSi byla vytvářena společně se specifikací, odpovídá implementace zcela specifikaci a neposkytuje nic navíc. Na příštích stránkách již tedy nebudu popisovat všechny implementační detaily jednotlivých tříd, které jsou předepsány specifikací CoSi. Jedná se například o rozhraní Bundle, jež je implementováno třídou BundleImpl. Metody, které jsou v této třídě, zcela odpovídají algoritmům popsaným ve specifikaci CoSi a tato specifikace se zároveň dá použit jako programátorská dokumentace k této, ale i jiným podobným třídám a rozhraním. V následujících kapitolách tedy popíši pouze principy spolupráce tříd a obecnou architekturu, na které je implementace frameworku CoSi založena. 7.1 Jádro kontejneru Jádro kontejneru se skládá z několika hlavních tříd, jejich funkčnost podporují třídy doplňkové. Hlavními třídami jsou: BDContainer hlavní třída celého systému, představující kontejner samotný. BundleManager obsahuje seznam nainstalovaných komponent - objektů typu BundleImpl jež jsou implementací rozhraní Bundle. Představuje statický pohled na kontejner a komponenty. ApplicationContext obsahuje informace o nainstalovaných komponentách co poskytují, co vyžadují atd. Také obsahuje registr služeb a metody pro práci s ním. Představuje dynamický pohled na kontejner a komponenty. 67

74 Na následujícím obrázku si ukážeme abstrakci vnitřní struktury kontejneru: BDContainer Obr. 7.1: Architektura tříd kontejneru Jak již bylo řečeno toto je hlavní třída kontejneru, která se nachází v balíčku cz.zcu.fav.kiv.bdcontainer. Je zodpovědná za start systému (metoda start() a stop()), za inicializaci celého kontejneru (s případnou konfigurací) a za nainstalování a spuštění základních systémových komponent (SystemService a MessageService, viz kapitoly níže). Poté co proběhne start kontejneru čeká vlákno na semaforu, který je uvolněn metodou stop() a tím se zastavuje celý kontejner. Ačkoliv to specifikace CoSi nepředepisuje, poskytuje BDContainer možnost jednoduchého konfiguračního souboru kontejneru. V tomto konfiguračním souboru se nachází seznam komponent, které mají být po startu kontejneru automaticky nainstalovány a spuštěny. Soubor nese jméno deploy.config a systém ho hledá v pracovním adresáři aplikace. Struktura tohoto souboru je popsána v něm samotném (je přiložen spolu se zdrojovými kódy na CD k této diplomové práci). O zpracování souboru se stará pomocná třída DeployConfigHelper (balí ek zcu.fav.kiv.bdcontainer.util). 68

75 BundleManager Tato třída obsahuje seznam nainstalovaných komponent, reprezentovaných instancemi třídy BundleImpl, která implementuje rozhraní Bundle předepisované specifikací CoSi. Tato třída poskytuje kromě metod pro práci s tímto seznamem také metody životního cyklu komponent na základě jejich identifikačního čísla (id). Tyto operace většinou sestávají z vyhledání příslušného objektu BundleImpl v seznamu a delegování požadavku na tento objekt. V celém systému existuje pouze jedna instance této třídy, čehož je dosaženo návrhovým vzorem Singleton ([GoF]). ApplicationContext Tato třída představuje dynamický pohled na kontejner. Obsahuje proměnné typu Collection, které v sobě drží informace o poskytovaných či vyžadovaných typech, rozhraních, atributech či zprávách jednotlivých komponent. Dále obsahuje metody, které usnadňují vyhledávání informací v těchto proměnných více se o těchto metodách dovíte přímo z javadoc dokumentace k této třídě (na CD přiloženém k této práci). Při operacích životního cyklu komponenty, jako je instalace, startování či aktualizace, se pracuje s těmito informacemi tak, aby byly vždy aktuální. Na základě těchto informací poté kontejner rozhoduje o tom, jestli bude komponenta nainstalována, spuštěna či jestli bude komponentě povoleno zastavení. Třída ApplicationContext je nejvíce využívána třídou BundleImpl, kde jsou implementace všech těchto operací životního cyklu. Třída také obsahuje registr služeb. Pokud komponenta přes svůj objekt BundleContext registruje instanci služby, je tato instance společně s jejím popisným objektem (ServiceReference implementovaný třídou ServiceReferenceImpl) uložena právě ve třídě ApplicationContext. Posledním významnou složkou této třídy jsou atributy komponent. Třída obsahuje proměnnou applicationattributes, která je typu HashMap. Tato proměnná obsahuje klíče a hodnoty atributů poskytovaných komponentami. Pokud komponenta přes svůj objekt BundleContext čte či zapisuje atributy, čte a zapisuje právě do této proměnné. V celém systému existuje pouze jedna instance této třídy, čehož je stejně jako u třídy BundleManager dosaženo návrhovým vzorem Singleton (viz [GoF]). GClassLoader Významnou součástí implementace kontejneru je i implementace classloaderu použitelného v prostředí CoSi. Specifikace pro takový classloader předepisuje 69

76 implementovat rozhraní ModuleClassLoader. Implementace tohoto rozhraní je realizována v balíčku cz.zcu.fav.kiv.bdcontainer.moduleloader třídou GClassLoader. Tento classloader vyhovuje specifikaci CoSi, je tedy schopen pracovat se soubory napsanými v jazyce Groovy, používá dynamickou classpath a v neposlední řadě přesně dodržuje algoritmus nahrávání tříd popsaný ve specifikaci. V tomto balíčku se také nachází třída DelegationManager, který usnadňuje vyhledávání classloaderů, které jsou zodpovědné na nahrávání tříd. Pokud například komponenta exportuje nějaký typ, je jméno tohoto typu zaneseno do DelegationManageru společně s referencí na classloader komponenty. V případě že jiná komponenta tento typ importuje, její classloader požádá DelegationManager o nahrání třídy classloaderem příslušné exportující komponenty. Podbalíček classpath obsahuje třídy poskytující implementaci dynamické classpath. Třída GClassPath je společně s ostatními třídami v tomto balíčku schopná udržovat dynamický seznam cest ke zdrojům a z těchto zdrojů číst. Třída je vytvořena se jménem.jar archivu, který je považován za kořenový adresář všech cest na classpath a všechny cesty musí být tedy relativní a musí vést ke zdrojům uvnitř tohoto archivu. Podstatným rozdílem oproti podobným třídám implementovaným přímo Javou je možnost odkazovat se na.jar archivy uvnitř kořenového.jar archivu a z těchto zdrojů číst data. Pro implementační detaily zkoumejte javadoc dokumentaci k tomuto balíčku a také zdrojový kód samotný. 7.2 Implementace systémových služeb Specifikace Cosi předepisuje implementovat základní služby systému tzv. systémové služby. Jedná se o: Služba SystemService poskytuje základní ovládání životních cyklů komponent a zjišťování informací o kontejneru. MessageService poskytuje systém zpráv, které si komponenty mohou vyměňovat. V následujícím textu se podíváme na to jak jsou tyto služby implementovány a kde jsou uloženy jejich kódy. Jak tyto služby fungují a jak s nimi pracovat je dostatečně podrobně popsáno ve specifikaci CoSi, nemá tedy smysl zde tyto informace opakovat. Zaměřme se tedy na samotnou implementaci. Systémové služby obecně Systémové služby jsou implementovány jako součást kontejneru, kde jsou pro ně 70

77 uměle vytvořeny komponenty. To znamená, že tyto komponenty nejsou uloženy ve speciálních.jar archivech, ale jsou součástí distribučního jaru kontejneru. Každá služba je uložena v příslušném balíčku, který obsahuje implementaci služby a manifest pro uměle vytvářenou komponentu. Pro takto uměle vytvářené komponenty byl vytvořen objekt typu SystemBundle, který je potomkem typu BundleImpl. Systémová komponenta může tedy být používána a chová se jako jiné komponenty (má svůj aktivátor, manifest, id atd.) s tím rozdílem, že její vytvoření je odlišné: Pro systémové komponenty není zapotřebí vytvářet GClassLoader tedy classloader, který pracuje s Groovy. Systémové služby jsou totiž napsány v Javě (stejně jako zbytek kontejneru), používají classpath, která je shodná s classpath kontejneru a o které víme že se za běhu nebude měnit, a nejsou závislé na jiných komponentách. Typ SystemBundle tedy přetěžuje metodu createbundleclassloader(), která místo vytvoření instance typu GClassLoader, jak je tomu běžné u normálních komponent, vrací instanci typu SystemBundleClassLoader. Tento speciální classloader nepodporuje dynamickou změnu classpath a deleguje všechny požadavky na základní classloader kontejneru. Toto vše mi umožnilo jednodušší práci se systémovými komponentami, jejich snazší začlenění do kódu kontejneru a v neposlední řadě také zvýšení rychlosti instalace a startu těchto komponent. Druhým rozdílem při vytváření systémových komponent je způsob získání manifestu komponenty. U normální komponenty je manifest hledán v adresáři META-INF v distribučním archivu komponenty. Jelikož systémové komponenty jsou uloženy spolu s kódem kontejneru v jednom archivu, toto není možné. Třída SystemBundle tedy přetěžuje metodu readmanifestfrombundle(), která vrácení dat manifestu ošetřuje jinak text manifestu je třídě SystemBundle předáván při jejím vytvoření a metoda pouze vrací InputStream na tento řetězec Služba SystemService Tato služba je do kontejneru zaregistrována těsně po startu kontejneru (metoda BDContainer.processSystemBundles()). Příslušná systémová komponenta je nainstalována s identifikačním číslem 0. Je to tedy první služba, která je nainstalována a spuštěna. Kód implementující tuto službu se nachází v distribučním archivu kontejneru v balíčku cz.zcu.fav.kiv.bdcontainer.systemservice. Podbalíček impl obsahuje aktivátor služby (SystemBundleActivator) a samotnou implementaci služby (SystemServiceImpl). Vše je doplněno o manifest systémové komponenty, který je uložen v podbalíčku manifest. Zde je textový soubor obsahující manifest a třída (Manifest.java), která usnadňuje práci s tímto textovým souborem. 71

78 Implementace služby je založena na prosté delegaci požadavků na jiné třídy v systému. Operace životního cyklu komponent jsou delegovány na korespondující operace ve třídě BundleManager. Metody poskytující informace o stavu kontejneru (nainstalované služby, poskytované typy, rozhraní atd.) delegují tyto požadavky na odpovídající metody ve třídě ApplicationContext Služba MessageService Služba zpráv je do kontejneru nainstalována jako druhá v pořadí (metoda BDContainer.processSystemBundles()), hned po dokončení instalace a spuštění služby SystemService. Příslušná systémová komponenta je nainstalována s identifikačním číslem 0 - je to tedy druhá služba, která je nainstalována a spuštěna. Kód implementující tuto službu se nachází v distribučním archivu kontejneru v balíčku cz.zcu.fav.kiv.bdcontainer.messageservice. Podbalíček impl obsahuje aktivátor služby (Activator) a samotnou implementaci služby (MessageServiceImpl). Kromě toho je zde ještě třída starající se o asynchronní doručování zpráv - AsyncMessageInvoker. Vše je doplněno o manifest systémové komponenty, který je uložen v podbalíčku manifest. Zde je textový soubor obsahující text manifestu a třída (Manifest.java), která usnadňuje práci s tímto textovým souborem. Funkcionalita této služby je již dostatečně popsána ve specifikaci CoSi a není zde důvod tuto funkcionalitu dále rozvádět, jelikož implementace služby neposkytuje nic navíc. Zmíním se pouze o způsobu doručování zpráv: Synchronní (blokující) doručování je řešeno přímým voláním přijímačů v cyklu se tedy procházejí všechny přijímače schopné danou zprávu přijmout a jejich jejich metoda receivemessage() je volána přímo. Vše probíhá ve vlákně odesílatele zprávy. Pro asynchronní doručování zpráv služba při svém startu vytváří speciální vlákno (AsyncMessageInvoker), které se o doručování zpráv stará. Pokud tedy odesilatel zprávy zavolá na službě metodu postmessage(), služba tomuto vláknu předá data o zprávě a komu má být tato zpráva doručena a ukončí metodu postmessage(). Vlákno se poté samo postará o doručení zpráv. 7.3 Implementace doplňkových služeb Kromě základních systémových služeb, které jsou předepsány specifikací CoSi jsem implementoval i doplňkové služby, které poskytují obecně využitelný základ pro používání systému. Jedná se o: Služba SimpleShell jednoduchá příkazová řádka pro práci se systémem. 72

79 LogService služba poskytující prostředí pro jednotné logování. HttpService velmi jednoduchý webserver, který komponenty mohou využít pro publikování na www. Každá ze služeb je uložena v samostatné komponentě. V následujících kapitolách popíši architekturu jednotlivých komponent (programátorská dokumentace) a také jak tyto služby používat (uživatelská dokumentace) Služba SimpleShell Jednou ze základních služeb pro interakci se systémem je příkazová řádka, implementována komponentou simpleshell.jar. Pomocí této příkazové řádky může uživatel po startu kontejneru zadávat základní příkazy pro jeho ovládání. Standardní příkazy zahrnují ovládání životních cyklů komponent (instalace, startování, aktualizace atd.) a zjišťování informací o stavu kontejneru a celého systému (stavy komponent, závislosti mezi komponentami, registrované služby atd.). Kromě standardních příkazů tato komponenta poskytuje službu, kterou lze využít k registraci nových příkazů. Komponenty tedy mohou využít tuto službu pro implementaci jednoduchého uživatelského rozhraní. Komponenta je kompletně napsána v jazyce Groovy. Aktivátor komponenty Aktivátor komponenty se nachází v balíčku cz.zcu.fav.simpleshell.impl a nese jméno Activator.groovy. Komponenta při svém startu spustí vlákno, které ze standardního vstupu kontejneru (dostupný přes BundleContext.getStdIn()) čte příkazy zadávané uživatelem a výsledky těchto příkazů vypisuje na standardní výstup (dostupný přes BundleContext.getStdOut()). Při startu se také do registru služeb kontejneru zaregistruje služba SimpleShell pod rozhraním cz.zcu.fav.simpleshell.simpleshell. Poskytované služby Komponenta poskytuje službu, do které je možné registrovat nové příkazy. Komponenta k tomuto účelu poskytuje interface Command, který představuje jeden příkaz příkazové řádky: public interface Command { public String gethelp(); public void docommand(string[] P_arguments); public String getname(); } Metoda gethelp() vrací krátký popis příkazu. Metoda getname() vrací jméno 73

80 příkazu, kterým bude v příkazové řádce vyvoláván. Toto jméno nesmí obsahovat mezery. Metoda docommand() je vyvolávána při volání příkazu. Jsou jí předávány argumenty příkazové řádky, se kterými byl příkaz vyvolán. Argumenty jsou všechny řetězce, které se vyskytují za jménem příkazu oddělené mezerou. Budeme-li například volat příkaz echo tímto voláním: echo Hello world!, bude pole P_arguments obsahovat dva prvky: [ Hello, world! ]. Komponenty implementují tento interface a tuto implementaci poté registrují do služby příkazem SimpleShell.registerCommand(Command). Služba je napsána ve stylu návrhového vzoru Command (viz [GoF]), to znamená, že příkazy mohou být do služby dynamicky přidávány či odebírány za běhu systému. Aby mohla komponenta tuto službu použít, musí ve svém manifestu specifikovat následující hlavičky: Require-Interfaces: cz.zcu.fav.simpleshell.simpleshell Require-Types: cz.zcu.fav.simpleshell.command Závislosti Jelikož tato komponenta obsahuje základní příkazy pro práci s životními cykly komponent a poskytuje příkazy, které zjišťují informace o systému, je závislá na systémové službě SystemService. Žádné jiné závislosti tato komponenta nemá. Popis balíčků Tato podkapitola obsahuje zkrácený popis významu balíčků, který tato komponenta obsahuje. Kód tříd není uzavřený a je k dispozici na CD k této práci. Pro detailní popis jednotlivých tříd si tedy prosím prohlédněte komentáře k jednotlivým třídám přímo v kódu. cz.zcu.fav.simpleshell Obsahuje rozhraní služby poskytované touto komponentou. Jedná se o rozhraní SimpleShell a rozhraní Command. cz.zcu.fav.simpleshell.impl Obsahuje aktivátor komponenty (Activator), implementaci služby SimpleShell (SimpleShellImpl), která přestavuje vlákno, které neustále čte standardní vstup a zpracovává příkazy, které uživatel zadá. Tyto příkazy rozparsuje (oddělí jméno příkazu od jeho argumentů) a podle jména příkazu vybere z registru příkazu konkrétní implementaci rozhraní Command, na které zavolá metodu docommand(). Třída SimpleShellImpl tedy obsahuje registr všech příkazů a také metody pro práci s tímto registrem (přidávání, odebírání). Poslední třídou v tomto balíku je ShellAccess rozhraní, které je 74

81 implementováno třídou SimpleShellImpl. Toto rozhraní je nutné, protože některé standardní příkazy potřebují přístup ke třídě SimpleShellImpl, nicméně SimpleShellImpl zase potřebuje přístup ke standardním příkazům. Tato situace by způsobovala zacyklení v importu tříd (circular reference). Standardním příkazům se tedy nepředává instance typu SimpleShellImpl, ale předává se rozhraní ShellAccess, který situaci se zacyklením řeší. cz.zcu.fav.simpleshell.impl.commands Tento balíček obsahuje implementace standardních příkazů. Popisy jednotlivých příkazů naleznete v komentářích přímo v kódu Služba LogService Komponenta logservice.jar poskytuje službu pro jednotné logování komponent. Každá z komponent by si mohla své logování řešit sama, nicméně tento způsob poskytuje centrální správu logů. Komponenta je založena na známe knihovně log4j, která je v současnosti jedním z nejvyspělejších frameworků pro logování. Aktivátor komponenty Aktivátor komponenty se nachází v balíčku cz.zcu.fav.kiv.logservice.impl a jedná se o třídu Activator. Při svém startu aktivátor pouze zaregistruje instanci služby LogService. Poskytované služby a typy Služba poskytuje systém, který je založen na záznamnících (logger), které mohou být nastaveny na určité úrovně. Tyto úrovně jsou definovány jako konstanty v rozhraní služby, kterým je cz.zcu.fav.kiv.logservice.logservice. Když je záznamník použit pro zalogování zprávy, je této zprávě přiřazena jedna z těchto úrovní. Podle toho na jakou úroveň je nastaven záznamník a s jakou úrovní se zpráva do záznamníku posílá se rozhodne, jestli bude zpráva zalogována či ne. Pokud je úroveň zprávy rovna či větší než úroveň záznamníku, pak je zpráva zalogována. Pokud je tomu naopak, je zpráva ignorována. Mějme například záznamník, který je nastaven na úroveň LOG_INFO. Všechny zprávy, které jsou logovány s úrovněmi LOG_INFO, LOG_WARN či LOG_ERROR budou zapsány do logu, protože tyto úrovně jsou větší nebo rovné úrovni, která je nastavena v záznamníku. Pokud se bude uživatel pokoušet zalogovat zprávu s úrovní LOG_DEBUG, bude tato ignorována a do logu se nezapíše. Služba poskytuje jeden předdefinovaný záznamník, který komponenty mohou využívat, pokud je jim jedno v jakém formátu a kam se zprávy budou zapisovat. K 75

82 nastavení úrovně tohoto globálního záznamníku se používá metoda setgloballevel(int) a k logování zpráv metody log(int, String) a log(int, String, Throwable). Je ale třeba míti na vědomí, že změnou úrovně tohoto záznamníku měníte úroveň i pro ostatní komponenty, které mohou tento společný záznamník používat. Pokud si komponenta využívající tuto službu chce nadefinovat vlastní záznamník, který nebude nikým jiným ovlivňován, může tak učinit pomocí konfigurační metody (configure(inputstream)), která akceptuje stream obsahující informace o záznamníku jako je jméno, výstupní formát atd. Tato implementace služby LogService je založena na knihovně Log4j, čili konfigurační metoda akceptuje standardní soubory log4j.properties. Pro detaily o tomto frameworku prosím navštivte stránky projektu - [L4J]. Protože každý záznamník má své jméno, můžete k těmto záznamníkům přistupovat přes jejich jméno pomocí metod log(string, int, String) a log(string, int, String, Throwable), kde prvním argumentem je právě jméno záznamníku, který chcete pro zápis do logu použít. Pro nastavení úrovně takového specifického záznamníku použijte metody setlevelfor(string, int). Závislosti Tato komponenta není závislá na žádných jiných komponentách či službách. Popis balíčků cz.zcu.fav.kiv.logservice Obsahuje pouze rozhraní služby LogService. cz.zcu.fav.kiv.logservice.impl Obsahuje implementaci služby spolu s aktivátorem komponenty Služba HttpService Komponenta httpservice.jar poskytuje jednoduchý web server založený na servletech podobných těm ve specifikaci J2EE, ale zjednodušených. Implementace samotného serveru je velmi jednoduchá, zvládá obsluhu jen základních požadavků protokolu HTTP1.1 GET a POST. Komponenta je doplněna o službu, kterou ostatní komponenty mohou použít pro registraci svých servletů a tím tedy využít funkcionality webserveru. Oproti ostatním doplňkovým službám je komponenta httpservice.jar napsána v čisté Javě, nepoužívá se zde tedy jazyk Groovy. 76

83 Aktivátor komponenty Aktivátor komponenty se nachází v balíčku cz.zcu.fav.kiv.httpservice.impl a jmenuje se Activator. Aktivátor při svém startu vytvoří instanci služby HttpService, zaregistruje tuto službu do kontejneru a spustí samotný webserver. Poskytované služby a typy Komponenta poskytuje službu, která je v registru služeb dostupná pod jménem cz.zcu.fav.kiv.httpservice.httpservice. Tento interface obsahuje pouze metody na registraci a deregistraci servletů do webserveru. Každý servlet je registrován s takzvaným mapováním. Mapování je jednoduchý řetězec a určuje adresu, pod kterou bude servlet na web serveru k dispozici. Pokud například zaregistrujete servlet s mapováním myservlet, pak tento servlet bude dostupný na adrese Mapování je pro každý servlet unikátní, znamená to tedy, že služba nezaregistruje servlet s mapováním, které už je použito jiným servletem. Kromě služby samotné poskytuje komponenta také typy nezbytné k používání služby. Těmito typy jsou Servlet, HttpRequest a HttpResponse. Komponenta, která chce registrovat svůj servlet do web serveru musí implementovat v jedné ze svých tříd rozhraní Servlet. Toto rozhraní obsahuje metody doget() a dopost(), které jsou serverem volány, jestliže internetový prohlížeč odeslal serveru příslušný požadavek (GET nebo POST). Obě metody mají dva parametry: HttpRequest a HttpResponse. Zatímco HttpRequest představuje informace o požadavku, který prohlížeč odeslal, HttpResponse je odpověď serveru prohlížeči. Detaily o těchto třídách prosím hledejte v javadoc dokumentaci k jednotlivým třídám. Závislosti Tato komponenta není nijak závislá na jiných komponentách. Popis balíčků cz.zcu.fav.kiv.httpservice Obsahuje rozhraní služby HttpService (HttpService.java) a další typy potřebné k využívání této služby (Servlet.java, HttpRequest.java a HttpResponse.java). Komponenty, které chtějí tuto službu využít by měly všechny tyto typy importovat. cz.zcu.fav.kiv.httpservice.impl Obsahuje kromě aktivátoru implementaci služby HttpService (HttpServiceImpl.java) a také implementaci web serveru (WebServer.java). Třída 77

84 WebServer k vyhledávání servletů, které má spouštět, používá registr servletů, který je uložen ve třídě HttpServiceImpl. cz.zcu.fav.kiv.httpservice.rootservlet Obsahuje základní servlet, který je do služby zaregistrován hned po jejím startu. Tento servlet funguje jako úvodní obrazovka a jako ukázkový příklad používání servletů. Kromě výpisu všech servletů zaregistrovaných ve službě je v metodě doget() předvedeno jak například pracovat s obrázky (implementace web serveru automaticky nevyřizuje požadavky žádající zdroje jako jsou obrázky, multimédia atd. - vše musí zpracovat příslušný servlet). V metodě dopost() je předvedeno jak pracovat s daty požadavku POST. 7.4 Ukázkový příklad Jako ukázku možnosti použití vytvořeného frameworku CoSi a jeho implementace jsem vytvořil jednoduchou aplikaci, která ukazuje možnosti použití této komponentové technologie. Jednou z možností jak použít komponenty k vytvoření aplikace je systém zásuvných modulů (plugin). Závěrečná kapitola popisuje ukázkový příklad textového editoru vylepšeného o zásuvné moduly, které zvýrazňují klíčová slova v textu (syntax highlighting). Architektura aplikace Aplikace se skládá z následujících komponent: editor.jar Hlavní aplikace, která zobrazuje okno editoru. highlighterregistry.jar Komponenta, která poskytuje službu udržující seznam zvýrazňovačů. sqlhighlighter.jar Zvýrazňovač souborů obsahujících sql skripty. javahighlighter.jar Zvýrazňovač zdrojových souborů napsaných v jazyce java. Obr. 7.2: Komponenty 78 ukázkového příkladu

Komponentní technologie

Komponentní technologie Komponentní technologie doc. Ing. Miroslav Beneš, Ph.D. katedra informatiky FEI VŠB-TUO A-1007 / 597 324 213 http://www.cs.vsb.cz/benes Miroslav.Benes@vsb.cz Obsah Motivace Aplikace v IT Vývoj přístupů

Více

INTEGRACE IS DO STÁVAJÍCÍ HW A SW ARCHITEKTURY

INTEGRACE IS DO STÁVAJÍCÍ HW A SW ARCHITEKTURY INTEGRACE IS DO STÁVAJÍCÍ HW A SW ARCHITEKTURY Dušan Kajzar Slezská univerzita v Opavě, Filozoficko-přírodovědecká fakulta, Bezručovo nám. 13, 746 00 Opava, e-mail: d.kajzar@c-box.cz Česká pošta, s.p.,

Více

OSGi. Aplikační programování v Javě (BI-APJ) - 6 Ing. Jiří Daněček Katedra softwarového inženýrství Fakulta informačních technologií ČVUT Praha

OSGi. Aplikační programování v Javě (BI-APJ) - 6 Ing. Jiří Daněček Katedra softwarového inženýrství Fakulta informačních technologií ČVUT Praha OSGi Aplikační programování v Javě (BI-APJ) - 6 Ing. Jiří Daněček Katedra softwarového inženýrství Fakulta informačních technologií ČVUT Praha Evropský sociální fond Praha & EU: Investujeme do vaší budoucnosti

Více

Tvorba podnikových aplikací v jazyce JAVA. Josef Pavlíček KII PEF CZU

Tvorba podnikových aplikací v jazyce JAVA. Josef Pavlíček KII PEF CZU Tvorba podnikových aplikací v jazyce JAVA Josef Pavlíček KII PEF CZU J2EE Jedná se o přístup: sadu pravidel, technologií, metod, doporučení jak provádět design, vývoj, nasazení a provozování vícevrstvých

Více

X33EJA Web Services. Martin Ptáček, KOMIX s.r.o.

X33EJA Web Services. Martin Ptáček, KOMIX s.r.o. X33EJA Web Services Martin Ptáček, KOMIX s.r.o. ptacek@komix.cz Copyright 2007 KOMIX Copyright s.r.o. 2007 KOMIX s.r.o. 1. Obsah Historie Co jsou Web Services? Co je to SOA? JAX-WS (Java API for XML Web

Více

Semináˇr Java X J2EE Semináˇr Java X p.1/23

Semináˇr Java X J2EE Semináˇr Java X p.1/23 Seminář Java X J2EE Seminář Java X p.1/23 J2EE Složitost obchodních aplikací robusní, distribuované, spolehlivé aplikace s transakcemi na straně serveru, klientské aplikace co nejjednodušší Snaha : Návrh,

Více

KIV/PIA 2013 Jan Tichava

KIV/PIA 2013 Jan Tichava KIV/PIA 2013 Jan Tichava Java EE JSF, PrimeFaces Spring JPA, EclipseLink Java Platform, Enterprise Edition Persistence Zobrazovací vrstva Interakce aplikací Deployment Java Persistence API Enterprise

Více

Softwarové komponenty a Internet

Softwarové komponenty a Internet Softwarové komponenty a Internet Doc. Dr. Ing. Miroslav Beneš Katedra informatiky FEI VŠB-TU Ostrava Miroslav.Benes@vsb.cz Obsah přednášky Motivace Vývoj přístupů k tvorbě programů Definice komponenty

Více

KAPITOLA 3. Architektura aplikací na frameworku Rails. V této kapitole: modely, pohledy, řadiče.

KAPITOLA 3. Architektura aplikací na frameworku Rails. V této kapitole: modely, pohledy, řadiče. KAPITOLA 3 Architektura aplikací na frameworku Rails V této kapitole: modely, pohledy, řadiče. 58 Část I: Začínáme Jedna ze zajímavých vlastností frameworku Rails spočívá v tom, že klade docela závažná

Více

IMPLEMENTACE SYSTÉMU GROUPWISE NA PEF ČZU V PRAZE IMPLEMENTATION OF THE SYSTEM GROUPWISE ON THE PEF ČZU PRAGUE. Jiří Vaněk, Jan Jarolímek

IMPLEMENTACE SYSTÉMU GROUPWISE NA PEF ČZU V PRAZE IMPLEMENTATION OF THE SYSTEM GROUPWISE ON THE PEF ČZU PRAGUE. Jiří Vaněk, Jan Jarolímek IMPLEMENTACE SYSTÉMU GROUPWISE NA PEF ČZU V PRAZE IMPLEMENTATION OF THE SYSTEM GROUPWISE ON THE PEF ČZU PRAGUE Jiří Vaněk, Jan Jarolímek Anotace: Příspěvek se zabývá hlavními trendy rozvoje programů pro

Více

Společnost Xerox vytváří škálovatelné, hostované řešení pro optimalizaci globální správy tiskových aktiv

Společnost Xerox vytváří škálovatelné, hostované řešení pro optimalizaci globální správy tiskových aktiv Microsoft Visual Studio 2005 a Microsoft SQL Server 2005 Případová studie zákaznického řešení Společnost Xerox vytváří škálovatelné, hostované řešení pro optimalizaci globální správy tiskových aktiv Přehled

Více

Technologie Java. Jaroslav Žáček jaroslav.zacek@osu.cz http://www1.osu.cz/~zacek/

Technologie Java. Jaroslav Žáček jaroslav.zacek@osu.cz http://www1.osu.cz/~zacek/ Technologie Java Jaroslav Žáček jaroslav.zacek@osu.cz http://www1.osu.cz/~zacek/ Trocha historie Java vznikla v roce 1995 jak minimalistický programovací jazyk (211 tříd). Syntaxe vycházela z C/C++. V

Více

IDENTITY MANAGEMENT Bc. Tomáš PRŮCHA

IDENTITY MANAGEMENT Bc. Tomáš PRŮCHA IDENTITY MANAGEMENT Bc. Tomáš PRŮCHA 20. 12. 2013 ÚVOD S penetrací IT do fungování společnosti roste důraz na zabezpečení důvěrnosti a opravdovosti (autenticity) informací a potvrzení (autorizaci) přístupu

Více

Správa a sledování SOA systémů v Oracle SOA Suite

Správa a sledování SOA systémů v Oracle SOA Suite Správa a sledování SOA systémů v Oracle SOA Suite Marek Rychlý Vysoké učení technické v Brně Fakulta informačních technologií Ústav informačních systémů Přednáška pro IOA 7. října 2014 Marek Rychlý Správa

Více

Servlety a JSP. Petr Adámek, petr.adamek@ibacz.eu

Servlety a JSP. Petr Adámek, petr.adamek@ibacz.eu Servlety a JSP Petr Adámek, petr.adamek@ibacz.eu Úvod Rekapitulace vstupních znalostí Standardy Nástroje (Běhové prostředí, nástroje pro vývoj) Servlety JSP JSP značky EL (Expression Language) Internacionalizace

Více

PA165: Úvod do Java EE. Petr Adámek

PA165: Úvod do Java EE. Petr Adámek PA165: Úvod do Java EE Petr Adámek Obsah přednášky Organizace předmětu Formy výuky Hodnocení Osnova Java EE aplikace Architektury Java EE aplikací Technologie Java EE Základní koncepty PA165: Úvod do Java

Více

Nástroje a frameworky pro automatizovaný vývoj. Jaroslav Žáček jaroslav.zacek@osu.cz http://www1.osu.cz/~zacek/

Nástroje a frameworky pro automatizovaný vývoj. Jaroslav Žáček jaroslav.zacek@osu.cz http://www1.osu.cz/~zacek/ Nástroje a frameworky pro automatizovaný vývoj Jaroslav Žáček jaroslav.zacek@osu.cz http://www1.osu.cz/~zacek/ Proces vývoje webové aplikace Předepsaná adresářová struktura. Kompilace zdrojových kódů.

Více

Projekty pro výuku programování v jazyce Java

Projekty pro výuku programování v jazyce Java JIHOČESKÁ UNIVERZITA V ČESKÝCH BUDĚJOVICÍCH Pedagogická fakulta Katedra informatiky Akademický rok: 2006/2007 TEZE BAKALÁŘSKÉ PRÁCE Projekty pro výuku programování v jazyce Java Jméno: František Přinosil

Více

Metodika. Architecture First. Rudolf Pecinovský rudolf@pecinovsky.cz

Metodika. Architecture First. Rudolf Pecinovský rudolf@pecinovsky.cz Copyright Rudolf Pecinovský, Soubor: 2014_Comm_PrW_Architecture First Methodology.doc, verze 1.00.2413, uloženo po 9.6.2014 14:43 1 z 39 Metodika Architecture First Rudolf Pecinovský rudolf@pecinovsky.cz

Více

Úvod. Petr Aubrecht (CA) Martin Ptáček (Wincor Nixdorf) Je 10 typů lidí: ti, kteří znají binární kód, a ti, kteří ne.

Úvod. Petr Aubrecht (CA) Martin Ptáček (Wincor Nixdorf) Je 10 typů lidí: ti, kteří znají binární kód, a ti, kteří ne. Úvod Petr Aubrecht (CA) Martin Ptáček (Wincor Nixdorf) Je 10 typů lidí: ti, kteří znají binární kód, a ti, kteří ne. Organizace předmětu Materiály k předmětu -Web stránky: http://cw.felk.cvut.cz/doku.php/courses/x33eja/start

Více

Co by měl umět dobrý vývojář. Petr Adámek Home Credit International a.s.

Co by měl umět dobrý vývojář. Petr Adámek Home Credit International a.s. Co by měl umět dobrý vývojář Petr Adámek Home Credit International a.s. 2 Vývoj software je Kreativní činnost Umění Věda Řemeslo Co je vlastně vývoj software? Vývoj software je průmyslová disciplína prováděná

Více

Statistica, kdo je kdo?

Statistica, kdo je kdo? Statistica, kdo je kdo? Newsletter Statistica ACADEMY Téma: Typy instalací Typ článku: Teorie Někteří z vás používají univerzitní licence, někteří síťové, podnikové atd. V tomto článku Vám představíme,

Více

Osnova. GIOP a IIOP IDL IOR POA. IDL Klient Server. 2 Historie. 3 Princip a základní pojmy. 4 Implementace. 5 Aplikace CORBA

Osnova. GIOP a IIOP IDL IOR POA. IDL Klient Server. 2 Historie. 3 Princip a základní pojmy. 4 Implementace. 5 Aplikace CORBA Common Object Request Broker Architecture FJFI ČVUT 9. 12. 2010 Osnova 1 2 3 4 5 Standard umožňující propojení aplikací psaných v různých jazycích a běžících na různých strojích a architekturách. Definuje

Více

MYBIZ - Řešení pro zpřístupnění dat ze stávajících aplikací na mobilních zařízeních (Mobilize your business!) Požadavky zákazníka.

MYBIZ - Řešení pro zpřístupnění dat ze stávajících aplikací na mobilních zařízeních (Mobilize your business!) Požadavky zákazníka. MYBIZ - Řešení pro zpřístupnění dat ze stávajících aplikací na mobilních zařízeních (Mobilize your business!) IT SYSTEMS a.s. Mnoho společností má implementovány aplikace, které byly vyvíjeny (případně

Více

Technologie Java Enterprise Edition. Přemek Brada, KIV ZČU 8.6.2011

Technologie Java Enterprise Edition. Přemek Brada, KIV ZČU 8.6.2011 Technologie Java Enterprise Edition Přemek Brada, KIV ZČU 8.6.2011 Přehled tématu Motivace a úvod Infrastruktura pro velké Java aplikace (Java základní přehled) Části třívrstvé struktury servlety, JSP

Více

UML - Unified Modeling Language

UML - Unified Modeling Language UML - Unified Modeling Language Martin Molhanec Katedra elektrotechnologie, ČVUT - Fakulta elektrotechnická, Technická 2, 166 21 PRAHA 6 e-mail: molhanec@fel.cvut.cz Abstrakt UML Unified Modeling Language

Více

Microsoft Office 2003 Souhrnný technický dokument white paper

Microsoft Office 2003 Souhrnný technický dokument white paper Microsoft Office 2003 Souhrnný technický dokument white paper Přehled inteligentních klientských aplikací založených na sadě Microsoft Office 2003 System Publikováno: Duben 2003 Shrnutí: Inteligentní klienti

Více

Common Object Request Broker Architecture

Common Object Request Broker Architecture Common Object Request Broker Architecture Tvorba aplikací, jejichž komponenty budou komunikovat přes počítačovou síť Programátor jedné aplikace volá metody vzdálených objektů podobně jako u sebe lokální

Více

7 Jazyk UML (Unified Modeling Language)

7 Jazyk UML (Unified Modeling Language) 7 Jazyk UML (Unified Modeling Language) 7.1 Základní charakteristika jazyka Motivace - vznik řady OO metod a metodologií (konec 80. let a první polovina 90.let) podobné notace vyjadřující totéž, komplikující

Více

VYUŽITÍ REGIONÁLNÍCH FUNKCÍ A WWW ROZHRANÍ V INTEGROVANÉM KNIHOVNÍM SYSTÉMU KPWINSQL

VYUŽITÍ REGIONÁLNÍCH FUNKCÍ A WWW ROZHRANÍ V INTEGROVANÉM KNIHOVNÍM SYSTÉMU KPWINSQL VYUŽITÍ REGIONÁLNÍCH FUNKCÍ A WWW ROZHRANÍ V INTEGROVANÉM KNIHOVNÍM SYSTÉMU KPWINSQL Petr Štefan Václav Trunec, KP-sys, Čacké 155, Pardubice 1 Úvod Firma KP-SYS spol. s r. o. dodává na náš trh integrované

Více

(Enterprise) JavaBeans. Lekce 7

(Enterprise) JavaBeans. Lekce 7 (Enterprise) JavaBeans Lekce 7 JavaBeans vs. Enterprise JavaBeans (EJB) JavaBeans technologie: jedná se o tzv. komponentní architekturu určenou pro JSE platformu určená pro tvorbu JSE GUI programů pomocí

Více

Platformy / technologie. Jaroslav Žáček jaroslav.zacek@osu.cz

Platformy / technologie. Jaroslav Žáček jaroslav.zacek@osu.cz Platformy / technologie Jaroslav Žáček jaroslav.zacek@osu.cz Které platformy / technologie znáte Java Java Java EE 5 Java EE 6 Pruning, Extensibility Ease of Dev, CDI, JAX-RS Java EE 7! JMS 2, Batch, Concurrency,

Více

7 Jazyk UML (Unified Modeling Language)

7 Jazyk UML (Unified Modeling Language) 7 Jazyk UML (Unified Modeling Language) 7.1 Základní charakteristika jazyka Motivace - vznik řady OO metod a metodologií (konec 80. let a první polovina 90.let) podobné notace vyjadřující totéž, komplikující

Více

Úvod do CORBY. Svetlozara Arabadzhieva 6.12.2006

Úvod do CORBY. Svetlozara Arabadzhieva 6.12.2006 Úvod do CORBY Svetlozara Arabadzhieva 6.12.2006 6.12.2006 Co je to CORBA? Common Object Request Broker Architecture Definice: Jazykov ě nezávislý objektový model a specifikace vývojového prostředí pro

Více

TÉMATICKÝ OKRUH Softwarové inženýrství

TÉMATICKÝ OKRUH Softwarové inženýrství TÉMATICKÝ OKRUH Softwarové inženýrství Číslo otázky : 25. Otázka : Komponentní technologie - základní pojmy a principy, metody specifikace komponent. Obsah : 1. Základní pojmy 1.1 Komponenta Komponenta

Více

Modelování webových služeb v UML

Modelování webových služeb v UML Modelování webových služeb v UML Jaromír Šveřepa LBMS, s.r.o. Abstrakt: Tento příspěvek se zaměřuje na praktický postup pro identifikaci potřeby webové služby, modelování způsobu jejího použití, popřípadě

Více

Architektury informačních systémů

Architektury informačních systémů Architektury informačních systémů doc. Ing. Miroslav Beneš, Ph.D. katedra informatiky FEI VŠB-TUO A-1007 / 597 324 213 http://www.cs.vsb.cz/benes/vyuka/tis Miroslav.Benes@vsb.cz Obsah přednášky Co je to

Více

Delphi podstata, koncepce a metody MDI aplikace

Delphi podstata, koncepce a metody MDI aplikace Delphi podstata, koncepce a metody MDI aplikace Bc. Tomáš Selucký, Ústav statistiky a operačního výzkumu, Provozně ekonomická fakulta, Mendelova zemědělská a lesnická univerzita v Brně, selucky@selucky.com

Více

Architektury informačních systémů

Architektury informačních systémů Architektury informačních systémů doc. Ing. Miroslav Beneš, Ph.D. katedra informatiky FEI VŠB-TUO A-1007 / 597 324 213 http://www.cs.vsb.cz/benes/vyuka/tis Miroslav.Benes@vsb.cz Obsah přednášky Co je to

Více

Infrastruktura UML. Modelování struktury v UML. Superstruktura UML. Notace objektů. Diagramy objektů

Infrastruktura UML. Modelování struktury v UML. Superstruktura UML. Notace objektů. Diagramy objektů Infrastruktura UML v UML Karel Richta listopad 2011 Richta: B101TMM - v UML 2 Superstruktura UML Směr pohledu na systém dle UML Diagramy popisující strukturu diagramy tříd, objektů, kompozitní struktury,

Více

1. Distribuce Javy. 2. Vlastnosti J2EE aplikace. 3. Fyzická architektura J2EE aplikace. Distribuce Javy se liší podle jejího zamýšleného použití:

1. Distribuce Javy. 2. Vlastnosti J2EE aplikace. 3. Fyzická architektura J2EE aplikace. Distribuce Javy se liší podle jejího zamýšleného použití: Architektura webové aplikace, funkce jednotlivých vrstev, životní cyklus standardizovaných komponent Java EE, Servlety, JSP, frameworky, návrhové vzory 1. Distribuce Javy Distribuce Javy se liší podle

Více

1 ÚVOD DO BPM. 1.1 Stručná historie BPM 5 KONTROLNÍ OTÁZKA 1. 1.1.1 Potřeba ohodnocení obchodu

1 ÚVOD DO BPM. 1.1 Stručná historie BPM 5 KONTROLNÍ OTÁZKA 1. 1.1.1 Potřeba ohodnocení obchodu 5 KONTROLNÍ OTÁZKA 1 1 ÚVOD DO BPM 1.1 Stručná historie BPM 1.1.1 Potřeba ohodnocení obchodu Když lidé poprvé začali žití ve společenských skupinách, několik lidí objevilo příležitost obchodovat se zbožím

Více

PŘÍPADOVÁ STUDIE ÚŘAD MĚSTSKÉ ČÁSTI PRAHA 3

PŘÍPADOVÁ STUDIE ÚŘAD MĚSTSKÉ ČÁSTI PRAHA 3 PŘÍPADOVÁ STUDIE ÚŘAD MĚSTSKÉ ČÁSTI PRAHA 3 Městská část Praha 3 se nachází na východ od centra metropole, její území tvoří pražská čtvrť Žižkov a část Královských Vinohrad. Úřad městské části Praha 3

Více

Tvorba informačních systémů

Tvorba informačních systémů Tvorba informačních systémů Michal Krátký 1, Miroslav Beneš 1 1 Katedra informatiky VŠB Technická univerzita Ostrava Tvorba informačních systémů, 2005/2006 c 2006 Michal Krátký, Miroslav Beneš Tvorba informačních

Více

NOVINKY V JEE EJB 3.1. Zdeněk Troníček Fakulta informačních technologií ČVUT v Praze

NOVINKY V JEE EJB 3.1. Zdeněk Troníček Fakulta informačních technologií ČVUT v Praze NOVINKY V JEE EJB 3.1 Zdeněk Troníček Fakulta informačních technologií ČVUT v Praze PROGRAM Seznámení s Java Enterprise Edition (JEE) Enterprise Java Beans (EJB) Novinky v EJB 3.1 2 JAVA EDITIONS Java

Více

Vedení a technologie: Výhody videokomunikace pro středně velké podniky

Vedení a technologie: Výhody videokomunikace pro středně velké podniky DOKUMENT WHITE PAPER Vedení a technologie: Výhody videokomunikace pro středně velké podniky Prosinec 2012 Shrnutí Středně velké podniky se snaží dosáhnout úspěchu v silně konkurenčním prostředí. Být úspěšný

Více

Převod prostorových dat katastru nemovitostí do formátu shapefile

Převod prostorových dat katastru nemovitostí do formátu shapefile GIS Ostrava 2009 25. - 28. 1. 2009, Ostrava Převod prostorových dat katastru nemovitostí do formátu shapefile Karel Janečka1, Petr Souček2 1Katedra matematiky, Fakulta aplikovaných věd, ZČU v Plzni, Univerzitní

Více

Unifikovaný modelovací jazyk UML

Unifikovaný modelovací jazyk UML Unifikovaný modelovací jazyk UML Karel Richta katedra počíta tačů FEL ČVUT Praha richta@fel fel.cvut.czcz Motto: Komunikačním m prostředkem informační komunity se postupem času stala angličtina. Chcete-li

Více

Návrh aplikace. Project Westpon. Inteligentní simulátor budov. Martin Mudra, Jan Smejkal, Onřej Macoszek, Marek Žehra, Jiří Slivárich

Návrh aplikace. Project Westpon. Inteligentní simulátor budov. Martin Mudra, Jan Smejkal, Onřej Macoszek, Marek Žehra, Jiří Slivárich Návrh aplikace Project Westpon Inteligentní simulátor budov Martin Mudra, Jan Smejkal, Onřej Macoszek, Marek Žehra, Jiří Slivárich . Úvod.. Účel dokumentu Tento dokument má za účel detailně popsat návrh

Více

RESTful web service v Javě

RESTful web service v Javě Mendelova univerzita v Brně Provozně ekonomická fakulta RESTful web service v Javě Literární rešerše práce Vedoucí práce: Ing. Jan Turčínek, Ph.D. Pavel Savrov Brno 2016 OBSAH 2 Obsah 1 Protokoly implementaci

Více

Návrh softwarových systémů - architektura softwarových systémů

Návrh softwarových systémů - architektura softwarových systémů Návrh softwarových systémů - architektura softwarových systémů Jiří Šebek Návrh softwarových systémů (B6B36NSS) Převzato z přednášky X36AAS M. Molhanec Co je to architektura 2 Využívá se v různách oborech

Více

Řízení ICT služeb na bázi katalogu služeb

Řízení ICT služeb na bázi katalogu služeb Řízení ICT služeb na bázi katalogu služeb Jiří Voř katedra IT, IT, VŠE vorisek@vse.cz nb.vse.cz/~vorisek 1 Služby fenomén současné etapy rozvoje společnosti 2 Vlastnosti služeb služby se od produktů liší

Více

USI - 102 - Projekt klíčenka"

USI - 102 - Projekt klíčenka USI - 102 - Projekt klíčenka" Předmět A7B36USI paralelka 102 Pondělí 14:30 cvičící Martin Komárek ČVUT FEL Tomáš Záruba, Gulnara Abilova, Martin Karban, Levan Bachukuri Termín odevzdání: 6.října 2013 Link

Více

Sem vložte zadání Vaší práce.

Sem vložte zadání Vaší práce. Sem vložte zadání Vaší práce. České vysoké učení technické v Praze Fakulta informačních technologií Katedra softwarového inženýrství Bakalářská práce Tvorba formulářů z popisu v XML s použitím knihovny

Více

RMI - Distribuované objekty v Javě

RMI - Distribuované objekty v Javě Vysoká škola báňská - Technická univerzita Ostrava 30. března 2009 Osnova Co je to RMI? 1 Co je to RMI? 2 Vnější pohled Vrstvy RMI Stub & Skeletons Layer Remote Reference Layer Transport Layer Pojemnování

Více

Katalog služeb a podmínky poskytování provozu

Katalog služeb a podmínky poskytování provozu Příloha č. 1 Servisní smlouvy Katalog služeb a podmínky poskytování provozu Část P2_1 P2_1_Katalog služeb a podmínky poskytování provozu 1 Obsah 1 OBSAH... 2 2 DEFINICE POJMŮ... 3 3 DEFINICE SLUŽEB, KOMPONENT

Více

Využití modelovacích nástrojů ve vývojářské firmě

Využití modelovacích nástrojů ve vývojářské firmě Vysoká škola ekonomická v Praze IT_572 Prostředky CASE a jejich využití při tvorbě IS Využití modelovacích nástrojů ve vývojářské firmě 11. prosince 2005 Jiří Pelc Petr Medřický Michal Pešička 1.Obsah

Více

Maven. Aplikační programování v Javě (BI-APJ) - 2 Ing. Jiří Daněček Katedra softwarového inženýrství Fakulta informačních technologií ČVUT Praha

Maven. Aplikační programování v Javě (BI-APJ) - 2 Ing. Jiří Daněček Katedra softwarového inženýrství Fakulta informačních technologií ČVUT Praha Maven Aplikační programování v Javě (BI-APJ) - 2 Ing. Jiří Daněček Katedra softwarového inženýrství Fakulta informačních technologií ČVUT Praha Evropský sociální fond Praha & EU: Investujeme do vaší budoucnosti

Více

Komponentový návrh SW

Komponentový návrh SW Komponentový návrh SW Komponentový návrh SW Komponenty jsou kompletně specifikované pomocí interface Jejich funkčnost je nezávislá na programovacím jazyku a mohou být integrované do toho samého systému

Více

Platforma J2EE. Lukáš Zapletal liberix.cz. Platforma Java 2 Enterprise Edition

Platforma J2EE. Lukáš Zapletal liberix.cz. Platforma Java 2 Enterprise Edition Platforma J2EE Lukáš Zapletal liberix.cz Platforma Java 2 Enterprise Edition Co je J2EE J2EE je standard pro vývoj robustních, škálovatelných a bezpečných serverových systémů v Javě. Poskytuje business

Více

Projektová dokumentace pro tvorbu internetových aplikací

Projektová dokumentace pro tvorbu internetových aplikací Projektová dokumentace pro tvorbu internetových aplikací Tomáš Kuthan PhDr. Milan Novák, Ph.D. Školní rok: 2008-09 Abstrakt Bakalářská práce stanovuje vzor pro vytváření projektové dokumentace internetových

Více

Uživatelem řízená navigace v univerzitním informačním systému

Uživatelem řízená navigace v univerzitním informačním systému Hana Netrefová 1 Uživatelem řízená navigace v univerzitním informačním systému Hana Netrefová Abstrakt S vývojem počítačově orientovaných informačních systémů je stále větší důraz kladen na jejich uživatelskou

Více

KAPITOLA 1 SOCIÁLNÍ SÍTĚ A PHP...17

KAPITOLA 1 SOCIÁLNÍ SÍTĚ A PHP...17 Obsah ÚVODEM..............................................11 Co v této knize najdete................................... 12 Co budete v této knize potřebovat.......................... 13 Pro koho je tato

Více

Integrace OpenOffice.org a Javy. CZJUG, , Robert Vojta

Integrace OpenOffice.org a Javy. CZJUG, , Robert Vojta Integrace OpenOffice.org a Javy CZJUG, 15.12.2008, Robert Vojta Obsah Část 1 - Teorie Úvodní informace, definice pojmů Dokumentace, Java Language Binding Pomocné nástroje Část 2 - Praktické ukázky Lokální

Více

Obrázek 6.14: Prohlížec nápovedy

Obrázek 6.14: Prohlížec nápovedy JavaHelp Základní popis systému JavaHelp Soucástí vetšiny interaktivních aplikací je nápoveda (help) aplikace v Jave nejsou výjimkou. Systém JavaHelp je napsaný v Jave a je urcený pro aplikace vytvárené

Více

Jedno globální řešení pro vaše Mezinárodní podnikání

Jedno globální řešení pro vaše Mezinárodní podnikání Jedno globální řešení pro vaše Mezinárodní podnikání Obsah 2 Známe váš svět, jsme jeho součástí 4 Správné řešení pro vaše mezinárodní podnikání 6 Standardní řešení s jedinečnými výhodami 8 Jedno globální

Více

VÝUKOVÝ MATERIÁL. Bratislavská 2166, 407 47 Varnsdorf, IČO: 18383874 www.vosassvdf.cz, tel. +420412372632 Číslo projektu

VÝUKOVÝ MATERIÁL. Bratislavská 2166, 407 47 Varnsdorf, IČO: 18383874 www.vosassvdf.cz, tel. +420412372632 Číslo projektu VÝUKOVÝ MATERIÁL Identifikační údaje školy Vyšší odborná škola a Střední škola, Varnsdorf, příspěvková organizace Bratislavská 2166, 407 47 Varnsdorf, IČO: 18383874 www.vosassvdf.cz, tel. +420412372632

Více

Operační systémy Linux, Mac OS X a jejich srovnání

Operační systémy Linux, Mac OS X a jejich srovnání 5 5.1 Operační systémy Linux, Mac OS X a jejich srovnání Popište výhody programů OpenSource, čím se vyznačují OpenSource programy se vyznačují tím, že se dodávají i se zdrojovým kódem. S tímto kódem může

Více

Enterprise Java (BI-EJA) Technologie programování v jazyku Java (X36TJV)

Enterprise Java (BI-EJA) Technologie programování v jazyku Java (X36TJV) Příprava studijního programu Informatika je podporována projektem financovaným z Evropského sociálního fondu a rozpočtu hlavního města Prahy. Praha & EU: Investujeme do vaší budoucnosti Enterprise Java

Více

PŘINÁŠÍME IT ŘEŠENÍ PRO FINANČNÍ ORGANIZACE. IT makes sense

PŘINÁŠÍME IT ŘEŠENÍ PRO FINANČNÍ ORGANIZACE. IT makes sense PŘINÁŠÍME IT ŘEŠENÍ PRO FINANČNÍ ORGANIZACE IT makes sense JSTE BANKA, ZÁLOŽNA ČI JINÁ FINANČNÍ ORGANIZACE A POTŘEBUJETE ZAJISTIT: Vedení běžných účtů Správu úvěrových produktů MÁME PRO VÁS ŘEŠENÍ Agendu

Více

Server-side technologie pro webové aplikace

Server-side technologie pro webové aplikace Server-side technologie pro webové aplikace PIA 2011/2012 Téma 6 Copyright 2006 Přemysl Brada, Západočeská univerzita Server-side scriptování Cíl dynamické generování webového obsahu/rozhraní integrace

Více

Architektura. Vedení sesterské dokumentace

Architektura. Vedení sesterské dokumentace Architektura Tým Lorem Ipsum Verze 1.1 29.3.2015 Obsah 1 Kontext...3 1.1 Cíle projektu...3 2 Technologie...3 2.1 Zvolená alternativa tvorby GUI...3 3 Datové schéma...4 4 Navržená architektura...5 4.1 Fyzický

Více

Tvorba informačních systémů

Tvorba informačních systémů Tvorba informačních systémů Michal Krátký 1, Miroslav Beneš 1 1 Katedra informatiky VŠB Technická univerzita Ostrava Tvorba informačních systémů, 2005/2006 c 2006 Michal Krátký, Miroslav Beneš Tvorba informačních

Více

Zabezpečení platformy SOA. Michal Opatřil Corinex Group

Zabezpečení platformy SOA. Michal Opatřil Corinex Group Zabezpečení platformy Michal Opatřil Corinex Group Agenda Současný přístup k bezpečnosti Požadavky zákazníků CA Security Manager Architektura Klíčové vlastnosti Proč CA Security Manager CA 2 Security Manager

Více

ELEARNING NA UJEP PŘEDSTAVY A SKUTEČNOST

ELEARNING NA UJEP PŘEDSTAVY A SKUTEČNOST ELEARNING NA UJEP PŘEDSTAVY A SKUTEČNOST JAN ČERNÝ, PETR NOVÁK Univerzita J.E. Purkyně v Ústí nad Labem Abstrakt: Článek popisuje problematiku rozvoje elearningu na UJEP. Snahu o vytvoření jednotného celouniverzitního

Více

George J. Klir. State University of New York (SUNY) Binghamton, New York 13902, USA gklir@binghamton.edu

George J. Klir. State University of New York (SUNY) Binghamton, New York 13902, USA gklir@binghamton.edu A Tutorial Advances in query languages for similarity-based databases George J. Klir Petr Krajča State University of New York (SUNY) Binghamton, New York 13902, USA gklir@binghamton.edu Palacky University,

Více

Návrh programu v Black Box Component Builderu s využitím architektury Model View Controller

Návrh programu v Black Box Component Builderu s využitím architektury Model View Controller Návrh programu v Black Box Component Builderu s využitím architektury Model View Controller Gustav Hrudka Katedra měřicí a řídicí techniky, VŠB Technická univerzita v Ostravě, tř. 17. listopadu, 708 33

Více

ADMINISTRACE POČÍTAČOVÝCH SÍTÍ. OPC Server

ADMINISTRACE POČÍTAČOVÝCH SÍTÍ. OPC Server ADMINISTRACE POČÍTAČOVÝCH SÍTÍ OPC Server Funkce a využití v průmyslové automatizaci Jiří NOSEK 2011 Co je OPC Server? OPC = Open Process Control (původně OLE for Process Control) sada specifikací průmyslového

Více

IBM TRIRIGA Application Platform Verze 3 Vydání 4.2. Příručka instalace a implementace

IBM TRIRIGA Application Platform Verze 3 Vydání 4.2. Příručka instalace a implementace IBM TRIRIGA Application Platform Verze 3 Vydání 4.2 Příručka instalace a implementace Poznámka Před použitím těchto informací a produktu, který podporují, si přečtěte informace v části Upozornění na stránce

Více

E-EDUCATION NEBOLI VYUŽITÍ ICT VE ŠKOLÁCH

E-EDUCATION NEBOLI VYUŽITÍ ICT VE ŠKOLÁCH E-EDUCATION NEBOLI VYUŽITÍ ICT VE ŠKOLÁCH ANDREA BAREŠOVÁ A KOL. Hewlett-Packard Abstrakt: e-education je název znamenající zapojení informačních technologií do výuky. S tímto pojmenováním přišla společnost

Více

ROZVOJ ICT A PDA ZAŘÍZENÍ THE DEVELOPMENT OF ICT AND PDA DEVICES Jiří Vaněk

ROZVOJ ICT A PDA ZAŘÍZENÍ THE DEVELOPMENT OF ICT AND PDA DEVICES Jiří Vaněk ROZVOJ ICT A PDA ZAŘÍZENÍ THE DEVELOPMENT OF ICT AND PDA DEVICES Jiří Vaněk Anotace: Příspěvek se zabývá rozvojem informačních a komunikačních technologií se zaměřením na trendy technického a programového

Více

Tvorba informačních systémů

Tvorba informačních systémů 9. Tvorba informačních systémů Michal Krátký, Miroslav Beneš Katedra informatiky VŠB Technická univerzita Ostrava Tvorba informačních systémů, 2007/2008 c 2006-2008 Michal Krátký, Miroslav Beneš Tvorba

Více

Úvod do programování v jazyce Java

Úvod do programování v jazyce Java Úvod do programování v jazyce Java Petr Krajča Katedra informatiky Univerzita Palackého v Olomouci 5. říjen, 2011 Petr Krajča (UP) KMI/UP3J: Seminář I. 5.10.2011 1 / 17 Organizační informace email: petr.krajca@upol.cz

Více

Letecká společnost zvyšuje svoji produktivitu a zkvalitňuje služby pomocí řešení pro správu webového obsahu

Letecká společnost zvyšuje svoji produktivitu a zkvalitňuje služby pomocí řešení pro správu webového obsahu Microsoft Office System Případová studie řešení zákazníka Letecká společnost zvyšuje svoji produktivitu a zkvalitňuje služby pomocí řešení pro správu webového obsahu Přehled Země nebo oblast: USA Odvětví:

Více

Implementace inkluzívního hodnocení

Implementace inkluzívního hodnocení Implementace inkluzívního hodnocení Závěrečným bodem první fáze projektu Agentury s názvem Hodnocení v inkluzívních podmínkách byla diskuze a posléze výklad konceptu inkluzívní hodnocení a formulace souhrnu

Více

VYUŽITÍ KNIHOVNY SWING PROGRAMOVACÍHO JAZYKU JAVA PŘI TVORBĚ UŽIVATELSKÉHO ROZHRANÍ SYSTÉMU "HOST PC - TARGET PC" PRO ŘÍZENÍ POLOVODIČOVÝCH MĚNIČŮ

VYUŽITÍ KNIHOVNY SWING PROGRAMOVACÍHO JAZYKU JAVA PŘI TVORBĚ UŽIVATELSKÉHO ROZHRANÍ SYSTÉMU HOST PC - TARGET PC PRO ŘÍZENÍ POLOVODIČOVÝCH MĚNIČŮ VYUŽITÍ KNIHOVNY SWING PROGRAMOVACÍHO JAZYKU JAVA PŘI TVORBĚ UŽIVATELSKÉHO ROZHRANÍ SYSTÉMU "HOST PC - TARGET PC" PRO ŘÍZENÍ POLOVODIČOVÝCH MĚNIČŮ Stanislav Flígl Katedra elektrických pohonů a trakce (K13114),

Více

SYSTÉM PRO KONFIGURACI KOMUNIKAČNÍCH TERMINÁLŮ A VIZUALIZACI STAVOVÝCH DAT Z KOLEJOVÝCH VOZIDEL

SYSTÉM PRO KONFIGURACI KOMUNIKAČNÍCH TERMINÁLŮ A VIZUALIZACI STAVOVÝCH DAT Z KOLEJOVÝCH VOZIDEL SYSTÉM PRO KONFIGURACI KOMUNIKAČNÍCH TERMINÁLŮ A VIZUALIZACI STAVOVÝCH DAT Z KOLEJOVÝCH VOZIDEL SYSTEM FOR CONFIGURATION OF COMMUNICATION TERMINALS AND VISUALIZATION OF STATE INFORMATION FROM RAIL VEHICLES

Více

Michal Krátký, Miroslav Beneš

Michal Krátký, Miroslav Beneš Tvorba informačních systémů 1/20 Tvorba informačních systémů Michal Krátký, Miroslav Beneš Katedra informatiky VŠB Technická univerzita Ostrava Tvorba informačních systémů, 2008/2009 Tvorba informačních

Více

Rational. Příručka ke správě licencí. Verze 7.0.1 Windows, UNIX a Linux GI11-2955-01

Rational. Příručka ke správě licencí. Verze 7.0.1 Windows, UNIX a Linux GI11-2955-01 Rational Verze 7.0.1 Windows, UNIX a Linux Příručka ke správě licencí GI11-2955-01 Rational Verze 7.0.1 Windows, UNIX a Linux Příručka ke správě licencí GI11-2955-01 Před použitím těchto informací se

Více

A7B36SI2 Tematický okruh SI08 Revidoval: Martin Kvetko

A7B36SI2 Tematický okruh SI08 Revidoval: Martin Kvetko Strategie testování, validace a verifikace. Testování v průběhu životního cyklu SW díla. Testování jednotek, integrační testování, validační testování, systémové testování, ladění. Principy testování,

Více

Malý průvodce Internetem

Malý průvodce Internetem Malý průvodce Internetem Úvod Toto povídání by mělo sloužit jako užitečný zdroj informací pro ty, co o Internetu zatím mnoho neví nebo o něm jen slyšeli a neví, co si pod tím slovem představit. Klade si

Více

JAK SE DAŘÍ KOMERČNÍMU LINUXU? Ondřej Suchý Enlogit s.r.o.

JAK SE DAŘÍ KOMERČNÍMU LINUXU? Ondřej Suchý Enlogit s.r.o. JAK SE DAŘÍ KOMERČNÍMU LINUXU? Ondřej Suchý Enlogit s.r.o. Část 1 O Enlogit Enlogit: o nás IT pro firmy primární zaměření: služby významný implementátor Linux & open source v ČR řešení serverové infrastruktury,

Více

Tvorba informačních systémů

Tvorba informačních systémů Tvorba informačních systémů Michal Krátký, Miroslav Beneš Katedra informatiky VŠB Technická univerzita Ostrava Tvorba informačních systémů, 2007/2008 c 2005-2008 Michal Krátký, Miroslav Beneš Tvorba informačních

Více

Vladimír Mach. @vladimirmach 2. 1. 2013

Vladimír Mach. @vladimirmach 2. 1. 2013 Vladimír Mach @vladimirmach 2. 1. 2013 SQL Server Compact Edition Jednoduchá relační databáze Použití i v malých zařízeních s omezenými zdroji Dříve pod názvem SQL Server Mobile Časté využití při programování

Více

X33EJA Enterprise Java

X33EJA Enterprise Java X33EJA Enterprise Java Petr Šlechta Sun Microsystems petr.slechta@sun.com Petr Aubrecht CA (Computer Associates) petr.aubrecht@ca.com X33EJA (2+2) Cvičení Formou samostatné práce na projektu témata budou

Více

Kentico CMS. Hledáte rychlý, snadný a efektivní způsob jak si vytvořit firemní web? Dál už hledat nemusíte. Snadné použití pro marketéry

Kentico CMS. Hledáte rychlý, snadný a efektivní způsob jak si vytvořit firemní web? Dál už hledat nemusíte. Snadné použití pro marketéry Hledáte rychlý, snadný a efektivní způsob jak si vytvořit firemní web? Dál už hledat nemusíte. Snadné použití pro marketéry Kvalitní a nepřetržitá globální podpora Flexibilní nástroj pro vývojáře Kentico

Více

Servisně orientovaná architektura a její aplikace v systémech sledování a řízení výroby

Servisně orientovaná architektura a její aplikace v systémech sledování a řízení výroby Servisně orientovaná architektura a její aplikace v systémech sledování a řízení výroby Marek Rychlý Vysoké učení technické v Brně Fakulta informačních technologií Ústav informačních systémů VII. ročník

Více

TÉMATICKÝ OKRUH Softwarové inženýrství

TÉMATICKÝ OKRUH Softwarové inženýrství TÉMATICKÝ OKRUH Softwarové inženýrství Číslo otázky : 29. Otázka : Zpracování událostí: mechanismus událostí a jejich zpracování (Event/Listener), nepřímá invokace (Observer/Observable). Obsah : 1. Mechanisums

Více

Michal Krátký, Miroslav Beneš

Michal Krátký, Miroslav Beneš Tvorba informačních systémů 1/32 Tvorba informačních systémů Michal Krátký, Miroslav Beneš Katedra informatiky VŠB Technická univerzita Ostrava Tvorba informačních systémů, 2008/2009 Tvorba informačních

Více

Architektura aplikace

Architektura aplikace Architektura aplikace MARBES-JIRA plugin Tým: GRSS Členové: František Schneider Jaroslav Ráb Lukáš Gemela Jaromír Staněk Upravil Verze dokumentu Datum F. Schneider 1.0 25.3.2012 F. Schneider 2.0 25.4.2012

Více