{"id":41,"date":"2013-02-03T14:26:32","date_gmt":"2013-02-03T13:26:32","guid":{"rendered":""},"modified":"2018-11-05T20:11:29","modified_gmt":"2018-11-05T19:11:29","slug":"kam-java-nemoze-posle-osgi-ii","status":"publish","type":"post","link":"https:\/\/spireng.sk\/en\/kam-java-nemoze-posle-osgi-ii\/","title":{"rendered":"Kam Java nem\u00f4\u017ee, po\u0161le OSGi II"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" class=\"imgp_img\" style=\"float: left; margin: 2px 5px;\" src=\"\/sites\/default\/files\/imagepicker\/1\/dsfsdfs.jpg\" alt=\"Obr\u00e1zok\" width=\"200\" height=\"215\" \/>OSGi je \u0161pecifik\u00e1cia modul\u00e1rneho java frameworku. \u00davod k tejto t\u00e9me n\u00e1jdete v jednom z mojich predch\u00e1dzaj\u00facich <a href=\"http:\/\/spireng.sk\/en\/kam-java-nemoze-posle-osgi\/\">\u010dl\u00e1nkov<\/a>. Okrem in\u00e9ho som v \u0148om nap\u00edsal, \u017ee cel\u00e1 OSGi aplik\u00e1cia je tvoren\u00e1 modulmi, ktor\u00e9 sa naz\u00fdvaj\u00fa bundle, a \u017ee tieto kusy k\u00f3du maj\u00fa ur\u010dit\u00fd \u017eivotn\u00fd cyklus. Teraz sa pozrieme presnej\u0161ie ako tak\u00fd bundle vyzer\u00e1 a ak\u00fdm \u017eivotom si v OSGi \u017eije.<!--more--><\/p>\n<p><!--break-->Bundle samo o sebe nie je v java svete ni\u010d mimoriadne. Je to \u0161tandardn\u00fd JAR s\u00fabor s .java s\u00fabormi vo vn\u00fatri (v spr\u00e1vnej adres\u00e1rovej \u0161trukt\u00fare). To, \u010do ho odli\u0161uje, s\u00fa metainform\u00e1cie zap\u00edsan\u00e9 v manifestovom s\u00fabore. Tie poskytuj\u00fa OSGi kontajneru (t.j. implement\u00e1cii OSGi \u0161pecifik\u00e1cie) inform\u00e1cie potrebn\u00e9 na to, aby vedel manipulova\u0165 s t\u00fdmto bal\u00edkom k\u00f3du. OSGi relevantn\u00e9 \u00fadaje v manifeste sa daj\u00fa rozdeli\u0165 do troch kateg\u00f3ri\u00ed:<\/p>\n<ol>\n<li>\u013eudsky \u010ditate\u013en\u00e9 inform\u00e1cie (nepovinn\u00e9) &#8211; napr\u00edklad meno bundlu,<\/li>\n<li>identifik\u00e1tory bundlu &#8211; \u010dasto s\u00fa to verzia a symbolick\u00e9 meno (vysvetlenie vi\u010f. ni\u017e\u0161ie),<\/li>\n<li>vidite\u013enos\u0165 k\u00f3du &#8211; inform\u00e1cie popisuj\u00face poskytovan\u00e9 a po\u017eadovan\u00e9 bal\u00edky pre dan\u00fd bundle.<\/li>\n<\/ol>\n<p>\u0160trukt\u00fara ka\u017ed\u00e9ho tak\u00e9hoto \u00fadaju je:<\/p>\n<p><em>Property-name: clause, clause, clause, &#8230;<\/em><\/p>\n<p>Pri\u010dom <span style=\"font-style: normal;\">\u0161trukt\u00fara <\/span><em>clause<\/em><span style=\"font-style: normal;\"> je nasledovn\u00e1:<\/span><\/p>\n<p><em>target1;paremeter1=value1;parameter2=value2;..<\/em>.<\/p>\n<p>Ve\u013emi zjednodu\u0161ene sa d\u00e1 poveda\u0165, \u017ee ka\u017ed\u00fd z\u00e1pis m\u00e1 n\u00e1zov a s\u00e9riu hodn\u00f4t oddelen\u00fdch \u010diarkami (<em>clause<\/em>). Ka\u017ed\u00e1 tak\u00e1to hodnota m\u00f4\u017ee ma\u0165 e\u0161te s\u00e9riu \u013eubovo\u013en\u00e9ho po\u010dtu parametrov oddelen\u00fdch bodko\u010diarkami (pri\u010dom parameter je op\u00e4\u0165 dvojica n\u00e1zov &#8211; hodnota). To je rozdelenie a \u0161trukt\u00fara. Ak\u00e9 konkr\u00e9tne \u00fadaje je tam mo\u017en\u00e9 n\u00e1js\u0165?<\/p>\n<p><span style=\"font-style: normal;\">Je to napr\u00edklad meno bundlu. To m\u00e1 dokonca a\u017e 2 z\u00e1pisy: <\/span><em>Name<\/em><span style=\"font-style: normal;\"> a <\/span><em>Bundle-SymbolicName <\/em><span style=\"font-style: normal;\">. To prv\u00e9 existuje od prvej verzie \u0161pecifik\u00e1cie a patr\u00ed do skupiny \u013eudsky \u010ditate\u013en\u00fdch inform\u00e1ci\u00ed. Je nepovinn\u00e9 a nemus\u00ed by\u0165 jedine\u010dn\u00e9. D\u00f4vod, pre\u010do je to tak, som u\u017e spomenul v predch\u00e1dzaj\u00facom \u010dl\u00e1nku. V\u00e4zby medzi bundlami s\u00fa v OSGi kontajnery na \u00farovni bal\u00edkov nie bundlov. To znamen\u00e1, \u017ee nepopisujem z\u00e1vislos\u0165 pomocou identifik\u00e1tora bundlu, ale n\u00e1zvu bal\u00edka. Aj preto bundle nemus\u00ed ma\u0165 meno alebo nemus\u00ed by\u0165 jedine\u010dn\u00e9. Od verzie 4 sa v \u0161pecifik\u00e1cii objavuje aj z\u00e1vislos\u0165 na bundly (je mo\u017en\u00e9 ju zadefinova\u0165, aj ke\u010f nie je odpor\u00fa\u010dan\u00e1), a preto prich\u00e1dza vlastnos\u0165 <\/span><em>Bundle-SymbolicName,<\/em><span style=\"font-style: normal;\"> ktor\u00e1 u\u017e mus\u00ed by\u0165 v r\u00e1mci jedn\u00e9ho OSGi kontajnera jedine\u010dn\u00e1 (a patr\u00ed do druhej skupiny, teda je to identifik\u00e1tor bundlu).<\/span><\/p>\n<p>\u010eal\u0161\u00ed d\u00f4le\u017eit\u00fd identifik\u00e1tor bundlu je verzia. T\u00e1 sa zapisuje v tvare:<\/p>\n<p><em>Version: major.minor.micro.qualifier <\/em><\/p>\n<p>pri\u010dom <em>major<\/em>, <em>minor<\/em> a <em>micro<\/em> s\u00fa povinn\u00e9 a mali by predstavova\u0165 \u010d\u00edslice a <em>qualifier<\/em> je nepovinn\u00fd a m\u00f4\u017ee obsahova\u0165 \u013eubovo\u013en\u00e9 znaky (napr\u00edklad d\u00e1tum zostavenia).<\/p>\n<p><span style=\"font-style: normal;\">Najpodstatnej\u0161ia je ale tretia skupina, ktor\u00e1 popisuje vidite\u013enos\u0165 k\u00f3du. Bundle m\u00f4\u017ee definova\u0165 bal\u00edky, ktor\u00fdch pr\u00edtomnos\u0165 vy\u017eaduje v OSGi kontajnery, aby mohol fungova\u0165 a tie\u017e bal\u00edky, ktor\u00e9 poskytuje pre ostatn\u00e9 bundle. To prv\u00e9 sa zapisuje pomocou vlastnosti s n\u00e1zvom <\/span><em>Import-Package <\/em><span style=\"font-style: normal;\">a predstavuje to zoznam n\u00e1zvov bal\u00edkov. Pre ka\u017ed\u00fd z nich je tie\u017e m\u00f4\u017en\u00e9 ma\u0165 definovan\u00fd zoznam parametrov, ktor\u00e9 s\u00fa vy\u017eadovan\u00e9 (napr\u00edklad m\u00f4j bundle po\u017eaduje \u0161pecifick\u00fa verziu bal\u00edka &#8211; toto sa pr\u00e1ve deje pomocou parametrov <\/span><em>clause<\/em><span style=\"font-style: normal;\"> v z\u00e1pise jednej vlastnosti). Podobne aj bal\u00edky, ktor\u00e9 bundle poskytuje, predstavuje zoznam mien zap\u00edsan\u00fdch vo vlastnosti <\/span><em>Export-Package <\/em><span style=\"font-style: normal;\">. Op\u00e4\u0165 m\u00f4\u017ee ma\u0165 ka\u017ed\u00fd tak\u00fdto bal\u00edk e\u0161te radu parametrov, medzi ktor\u00e9 patr\u00ed napr\u00edklad verzia.<\/span><\/p>\n<p><span style=\"font-style: normal;\">Importovan\u00e9 a exportovan\u00e9 bal\u00edky s\u00fa asi najd\u00f4le\u017eitej\u0161\u00edm OSGi \u00fadajom v manifeste. Na z\u00e1klade nich potom OSGi vyhodnocuje, \u010di je mo\u017en\u00e9 dan\u00fd bal\u00edk nasadi\u0165 v kontajnery (vyhodnocuje, \u010di s\u00fa v \u0148om pr\u00edtomn\u00e9 v\u0161etky po\u017eadovan\u00e9 bal\u00edky). A tie\u017e \u010do sa udeje, ak sa rozhodnete nejak\u00fd bundle odobra\u0165 alebo aktualizova\u0165 &#8211; OSGi vyvol\u00e1 s\u00e9riu vypnut\u00ed (a pr\u00edpadne op\u00e4tovn\u00fdch zapnut\u00ed) bundlov, ktor\u00e9 na odoberanom bundle z\u00e1visia. OSGi tie\u017e umo\u017e\u0148uje nasadi\u0165 nieko\u013eko bundlov, ktor\u00e9 poskytuj\u00fa ten ist\u00fd bal\u00edk r\u00f4znej alebo dokonca rovnakej verzie. \u0160pecifik\u00e1cia pritom popisuje pomerne zlo\u017eit\u00fd algoritmus ako n\u00e1js\u0165 ten spr\u00e1vny bal\u00edk, pri\u010dom OSGi sa sna\u017e\u00ed udr\u017ea\u0165 \u010do najkonzistentnej\u0161ie prostredie (\u010do najviac bundlov pou\u017e\u00edva ten ist\u00fd bal\u00edk). Popis situ\u00e1ci\u00ed, ktor\u00e9 m\u00f4\u017eu nasta\u0165 a ako sa s nimi OSGi vysporiada, je ale t\u00e9ma na samostatn\u00fd \u010dl\u00e1nok.<\/span><\/p>\n<p><span style=\"font-style: normal;\">Do tretej kateg\u00f3rie e\u0161te spad\u00e1 posledn\u00e1 d\u00f4le\u017eit\u00e1 vlastnos\u0165 s n\u00e1zvom <\/span><em>Bundle-ClassPath<\/em><span style=\"font-style: normal;\">. T\u00e1 popisuje cesty h\u013eadania z\u00e1vislost\u00ed pre k\u00f3d v danom bundle. Popisom toho, \u010do je class path som sa zaoberal v inom <a href=\"https:\/\/spireng.sk\/en\/content\/ceste-java-triedam\/\">\u010dl\u00e1nku<\/a>. Pre OSGi je d\u00f4le\u017eit\u00e9 poveda\u0165, \u017ee ka\u017ed\u00fd bundle m\u00e1 svoj vlastn\u00fd class loader. A ten (zhruba povedan\u00e9) nazer\u00e1 do troch mno\u017e\u00edn k\u00f3du: do kni\u017en\u00edc JVM, do bal\u00edkov, ktor\u00fd dan\u00fd bundle importuje a do k\u00f3du v r\u00e1mci dan\u00e9ho bundlu. Pr\u00e1ve t\u00fa tretiu mno\u017einu popisuje Bundle-ClassPath. S\u00fa to intern\u00e9 n\u00e1zvy bal\u00edkov v r\u00e1mci dan\u00e9ho bundlu. Ak ju do manifestu nezad\u00e1te, tak je nastaven\u00e1 na \u201e <\/span><span style=\"font-style: normal;\"><strong>. <\/strong><\/span><span style=\"font-style: normal;\">\u201c \u010do znamen\u00e1, \u017ee class loader m\u00e1 k dispoz\u00edcii v\u0161etok k\u00f3d, ktor\u00fd je v bundle. V \u0161pecifick\u00fdch pr\u00edpadoch sa ale m\u00f4\u017ee rozhodn\u00fa\u0165, \u017ee napr\u00edklad nejak\u00fd bal\u00edk chcete exportova\u0165, ale nechcete, aby bol z\u00e1rove\u0148 pou\u017e\u00edvan\u00fd k\u00f3dom v danom bundle a t\u00fato cestu pod\u013ea toho nastavi\u0165.<\/span><\/p>\n<p>Pochopenie manifestu je d\u00f4le\u017eit\u00e9, lebo takto ste schopn\u00ed zostavi\u0165 bundle &#8211; z\u00e1kladn\u00fd stavebn\u00fd prvok OSGi. \u010co sa ale deje s bundlom po tom, \u010do sa ho pok\u00fasite dosta\u0165 do OSGi kontajnera, vypoved\u00e1 \u010das\u0165 \u0161pecifik\u00e1cie, ktor\u00e1 sa zaober\u00e1 \u017eivotn\u00fdm cyklom. Ten sa d\u00e1 najlep\u0161ie pop\u00edsa\u0165 diagramom:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"imgp_img\" style=\"vertical-align: top; display: block; margin-left: auto; margin-right: auto;\" src=\"\/sites\/default\/files\/imagepicker\/1\/osgi.zivotny.cyklus.jpg\" alt=\"Obr\u00e1zok\" width=\"583\" height=\"421\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>V\u0161etko za\u010d\u00edna stavom <em>Installed<\/em>. V tomto stave sa bundle dost\u00e1va do OSGi kontajnera. Framework si vezme bundle a nakop\u00edruje do jeho vn\u00fatornej \u0161trukt\u00fary (tie\u017e naz\u00fdvaj <em>Bundle cache<\/em>). \u010eal\u0161\u00edm stavom je <em>Resolved,<\/em> \u010do je stav, kedy OSGi vyhodnot\u00ed, \u017ee po\u017eiadavky dan\u00e9ho bundlu s\u00fa splnen\u00e9. V podstate to znamen\u00e1, \u017ee v\u0161etky po\u017eadovan\u00e9 bal\u00edky tohto bundlu s\u00fa u\u017e k dispoz\u00edcii vo forme bal\u00edkov exportovan\u00fdch in\u00fdmi bundlami. Bundle je e\u0161te st\u00e1le v stave, \u017ee sa nepou\u017e\u00edva. Zatia\u013e je len nain\u0161talovan\u00fd a pripraven\u00fd na pou\u017eitie. Nasleduje pr\u00edkaz <em>start,<\/em> ktor\u00fd ho prepne najprv do do\u010dasn\u00e9ho stavu <em>Starting<\/em> a potom do stavu <em>Active<\/em>. Stav <em>Active<\/em> je v podstate cie\u013eov\u00fd stav, v ktorom by sa bundle mal ocitn\u00fa\u0165, aby spr\u00e1vne fungoval. Pr\u00e1ve v \u0148om s\u00fa exportovan\u00e9 bal\u00edky<span style=\"background: transparent;\"> in\u00fdm k dispoz\u00edcii <\/span>a k\u00f3d m\u00f4\u017ee by\u0165 pou\u017e\u00edvan\u00fd. Sp\u00e4\u0165 do stavu <em>Resolved<\/em> sa d\u00e1 vr\u00e1ti\u0165 cez pr\u00edkaz <em>stop<\/em> a medzistav <em>Stopping<\/em>. Pr\u00edkaz na odin\u0161talovanie bundlu sp\u00f4sob\u00ed, \u017ee sa najprv stopne (ak bol akt\u00edvny), potom sa prepne do <em>Resovled<\/em>, n\u00e1sledne do <em>Installed<\/em> a na z\u00e1ver do <em>Uninstalled<\/em>.<\/p>\n<p>Okrem t\u00fdchto spomenut\u00fdch prechodov s\u00fa v grafe e\u0161te dva, ktor\u00e9 sa dej\u00fa pri pr\u00edkaze <em>refresh\/update<\/em>. <em><span style=\"text-decoration: none;\">Update<\/span><\/em><span style=\"text-decoration: none;\"> v podstate znamen\u00e1 aktualiz\u00e1ciu bundlu &#8211; nahratie jeho nov\u0161ej verzie. Akt\u00edvny bundle sa mus\u00ed dosta\u0165 do stavu Installed, vymen\u00ed sa jeho <\/span><span style=\"text-decoration: none;\"><span style=\"background: transparent;\">bin\u00e1rne <\/span><\/span><span style=\"text-decoration: none;\">data (teda k\u00f3d) a znova mus\u00ed prejs\u0165 v\u0161etk\u00fdmi krokmi a\u017e do stavu <\/span><em><span style=\"text-decoration: none;\">Active<\/span><\/em><span style=\"text-decoration: none;\">. Nov\u00e1 verzia toti\u017e m\u00f4\u017ee ma\u0165 nov\u00e9 po\u017eiadavky, ktor\u00e9 nemusia by\u0165 splnite\u013en\u00e9. \u010co sa ale deje, ke\u010f takto aktualizujem nejak\u00fd bundlu, na ktorom s\u00fa z\u00e1visl\u00e9 in\u00e9? Bude <\/span><span style=\"text-decoration: none;\"><span style=\"background: transparent;\">nad<\/span><\/span><span style=\"text-decoration: none;\"> nimi vykonan\u00fd pr\u00edkaz <\/span><em><span style=\"text-decoration: none;\">Refresh<\/span><\/em><span style=\"text-decoration: none;\">. Ten sp\u00f4sob\u00ed, \u017ee sa z <\/span><em><span style=\"text-decoration: none;\">Active<\/span><\/em><span style=\"text-decoration: none;\"> stavu prepn\u00fa a\u017e do <\/span><em><span style=\"text-decoration: none;\">Installed<\/span><\/em><span style=\"text-decoration: none;\"> a odtia\u013e op\u00e4\u0165 postupne do stavu <\/span><em><span style=\"text-decoration: none;\">Active.<\/span><\/em><span style=\"text-decoration: none;\"> Op\u00e4\u0165 sa toti\u017e m\u00f4\u017ee sta\u0165, \u017ee nov\u00fd bundle neposkytuje niektor\u00fd bal\u00edk, ktor\u00fd jeho star\u00e1 verzia poskytovala a to treba o\u0161etri\u0165. Takto sa OSGi sna\u017e\u00ed udr\u017ea\u0165 v z\u00e1vislostiach integritu. Za \u017eiadnych okolnost\u00ed by sa nemalo sta\u0165, \u017ee bal\u00edk, ktor\u00fd je v stave <\/span><em><span style=\"text-decoration: none;\">Active,<\/span><\/em><span style=\"text-decoration: none;\"> nebude ma\u0165 pr\u00edstupn\u00e9 v\u0161etky svoje z\u00e1vislosti.<\/span><\/p>\n<p><span style=\"text-decoration: none;\">Pochopenie metad\u00e1t bundlu a jeho \u017eivotn\u00e9ho cyklu s\u00fa len \u010fal\u0161ie dva kroky k pochopeniu OSGi ako celku. \u0160pecifik\u00e1cia bola navrhnut\u00e1 dos\u0165 defenz\u00edvne, a tak pokia\u013e je dodr\u017ean\u00e1 v konkr\u00e9tnej implement\u00e1cii, nemalo by doch\u00e1dza\u0165 k zn\u00e1mym <\/span><em><span style=\"text-decoration: none;\">ClassNotFoundException,<\/span><\/em><span style=\"text-decoration: none;\"> kedy interpreter J<\/span><span style=\"text-decoration: none;\"><span style=\"background: transparent;\">avy<\/span><\/span><span style=\"text-decoration: none;\"> nem\u00e1 dostupn\u00e9 v\u0161etky triedy. D\u00f4le\u017eit\u00e9 je len spr\u00e1vne zadefinova\u0165 po\u017eiadavky bundlu a pochopi\u0165, \u010do sa s n\u00edm deje po tom, ako sa raz dostane do OSGi kontajn\u00e9ra.<\/span><\/p>","protected":false},"excerpt":{"rendered":"<p>OSGi je \u0161pecifik\u00e1cia modul\u00e1rneho java frameworku. \u00davod k tejto t\u00e9me n\u00e1jdete v jednom z mojich predch\u00e1dzaj\u00facich \u010dl\u00e1nkov. Okrem in\u00e9ho som v \u0148om nap\u00edsal, \u017ee cel\u00e1 OSGi aplik\u00e1cia je tvoren\u00e1 modulmi, ktor\u00e9 sa naz\u00fdvaj\u00fa bundle, a \u017ee tieto kusy k\u00f3du maj\u00fa ur\u010dit\u00fd \u017eivotn\u00fd cyklus. Teraz sa pozrieme presnej\u0161ie ako tak\u00fd bundle vyzer\u00e1 a ak\u00fdm \u017eivotom si [&hellip;]<\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[13],"tags":[],"class_list":["post-41","post","type-post","status-publish","format-standard","hentry","category-vyvoj-softveru"],"_links":{"self":[{"href":"https:\/\/spireng.sk\/en\/wp-json\/wp\/v2\/posts\/41","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/spireng.sk\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/spireng.sk\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/spireng.sk\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/spireng.sk\/en\/wp-json\/wp\/v2\/comments?post=41"}],"version-history":[{"count":2,"href":"https:\/\/spireng.sk\/en\/wp-json\/wp\/v2\/posts\/41\/revisions"}],"predecessor-version":[{"id":321,"href":"https:\/\/spireng.sk\/en\/wp-json\/wp\/v2\/posts\/41\/revisions\/321"}],"wp:attachment":[{"href":"https:\/\/spireng.sk\/en\/wp-json\/wp\/v2\/media?parent=41"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/spireng.sk\/en\/wp-json\/wp\/v2\/categories?post=41"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/spireng.sk\/en\/wp-json\/wp\/v2\/tags?post=41"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}