Úvod do OSGi

1. Úvod

Niekoľko kritických a middlewarových aplikácií Java má niektoré náročné technologické požiadavky.

Niektoré musia podporovať horúce nasadenie, aby nedošlo k prerušeniu bežiacich služieb - a iné musia byť schopné pracovať s rôznymi verziami rovnakého balíka, aby podporili externé staršie systémy.

The OSGi platformy predstavujú životaschopné riešenie na podporu tohto druhu požiadaviek.

The Iniciatíva otvorenej brány služieb je špecifikácia definujúca systém komponentov založený na prostredí Java. V súčasnosti ju spravuje Aliancia OSGia jeho prvá verzia pochádza z roku 1999.

Odvtedy sa ukázal ako vynikajúci štandard pre systémy komponentov a v dnešnej dobe je široko používaný. The Zatmenie IDEnapríklad je OSGi-základná aplikácia.

V tomto článku preskúmame niektoré základné funkcie aplikácie OSGi využitím implementácie poskytovanej Apache.

2. Základy OSGi

V OSGi sa jeden komponent nazýva zväzok.

Logicky, zväzok je časť funkčnosti, ktorá má nezávislý životný cyklus - čo znamená, že je možné ho spustiť, zastaviť a odstrániť nezávisle.

Technicky je zväzok iba súbor jar s MANIFEST.MF súbor obsahujúci niektoré hlavičky špecifické pre OSGi.

The OSGi platforma poskytuje spôsob prijímania upozornení na sprístupnenie balíkov alebo na ich odstránenie z platformy. To umožní správne navrhnutému klientovi pokračovať v práci, možno so zníženou funkčnosťou, aj keď je služba, na ktorej záleží, na chvíľu nedostupná.

Z tohto dôvodu musí balík výslovne deklarovať, ku ktorým balíkom musí mať prístup a OSGi platforma ju spustí, iba ak sú závislosti dostupné v samotnom balíku alebo v iných balíkoch už nainštalovaných na platforme.

3. Získanie nástrojov

Začneme našu cestu dovnútra OSGi stiahnutím najnovšej verzie Apache Karaf z tohto odkazu. Apache Karaf je platforma, ktorá beží OSGi-založené aplikácie; je to zalozene na ApacheSa vykonáva OSGi volala sa špecifikácia Apache Felix.

Karaf ponúka niektoré užitočné funkcie navyše Felix ktoré nám pomôžu pri zoznamovaní sa OSGi, napríklad rozhranie príkazového riadku, ktoré nám umožní interakciu s platformou.

Inštalovať Karaf, môžete postupovať podľa pokynov na inštaláciu z oficiálnej dokumentácie.

4. Vstupný bod balíka

Ak chcete spustiť aplikáciu v prostredí OSGi, musíme ju zbaliť ako OSGi zväzok a definovať vstupný bod aplikácie, a to nie je obvyklé public static void main (reťazec [] args) metóda.

Začnime teda stavbou OSGi- založená aplikácia „Hello World“.

Začíname nastavovať jednoduchú závislosť na jadre OSGi API:

 org.osgi org.osgi.core 6.0.0 k dispozícii 

Závislosť je deklarovaná ako za predpokladu pretože bude k dispozícii v OSGi runtime a zväzok ho nemusí vkladať.

Poďme teraz napísať jednoduché HelloWorld trieda:

verejná trieda HelloWorld implementuje BundleActivator {public void start (BundleContext ctx) {System.out.println ("Hello world."); } public void stop (BundleContext bundleContext) {System.out.println ("Zbohom svet."); }}

BundleActivator je rozhranie poskytované serverom OSGi ktorý musia implementovať triedy, ktoré sú vstupnými bodmi pre zväzok.

The štart () metóda je vyvolaná OSGi platforma pri spustení balíka obsahujúceho túto triedu. Na druhej strane stop () sa vyvolá skôr, ako sa balík zastaví.

Nezabudnite, že každý zväzok môže obsahovať najviac jeden BundleActivator. The BundleContext objekt poskytovaný oboma metódami umožňuje interakciu s OSGi beh programu. Čoskoro sa k tomu vrátime.

5. Zostavenie zväzku

Poďme upraviť pom.xml a urobiť z neho skutočný balík OSGi.

Najskôr musíme výslovne uviesť, že vytvoríme zväzok, nie nádobu:

zväzok

Potom využijeme maven-bundle-plugin, s láskavým dovolením Apache Felix spoločenstvo, zabaliť HelloWorld trieda ako OSGi zväzok:

 org.apache.felix maven-bundle-plugin 3.3.0 true $ {pom.groupId}. $ {pom.artifactId} $ {pom.name} $ {pom.version} com.baeldung.osgi.sample.activator.HelloWorld com.baeldung.osgi.sample.aktivátor 

V časti s pokynmi určujeme hodnoty parametra OSGi hlavičky, ktoré chceme zahrnúť do súboru MANIFEST balíka.

Balíček-aktivátor je plne kvalifikovaný názov BundleActivator implementácia, ktorá sa použije na spustenie a zastavenie zväzku, a týka sa triedy, ktorú sme práve napísali.

Súkromný balík nie je hlavička OSGi, ale slúži na to, aby sa doplnku povedalo, aby zahrnul balík do zväzku, ale nesprístupnil ho iným. Teraz môžeme zostaviť balík pomocou obvyklého príkazu mvn čistá inštalácia.

6. Inštalácia a spustenie balíka

Začnime Karaf vykonaním príkazu:

/ bin / karaf štart

kde je priečinok, kde Karaf je nainštalovaný. Po výzve Karaf keď sa zobrazí konzola, môžeme vykonať nasledujúci príkaz na inštaláciu balíka:

> balík: install mvn: com.baeldung / osgi-intro-sample-activator / 1.0-SNAPSHOT ID balíka: 63

Toto dáva Karafu pokyn na načítanie zväzku z miestneho úložiska Maven.

Na oplátku Karaf vytlačí číselné ID priradené balíku, ktoré závisí od počtu už nainštalovaných balíkov a môže sa líšiť. Balík je teraz práve nainštalovaný, teraz ho môžeme spustiť nasledujúcim príkazom:

> balíček: štart 63 Hello World

Hneď ako sa zväzok spustí, okamžite sa zobrazí „Hello World“. Teraz môžeme balík zastaviť a odinštalovať pomocou:

> balík: stop 63> balík: odinštalovať 63

Na konzole sa objaví „Goodbye World“, podľa kódu v stop () metóda.

7. Služba OSGi

Poďme písať ďalej OSGi služba, rozhranie, ktoré sprístupňuje spôsob pozdravu ľudí:

balíček com.baeldung.osgi.sample.service.definition; verejné rozhranie Greeter {public String sayHiTo (názov reťazca); }

Napíšme jeho implementáciu, ktorá je a BundleActivator takže budeme môcť vytvoriť inštanciu služby a zaregistrovať ju na platforme pri spustení balíka:

balíček com.baeldung.osgi.sample.service.implementácia; verejná trieda GreeterImpl implementuje Greeter, BundleActivator {private ServiceReference reference; súkromná registrácia ServiceRegistration; @Override public String sayHiTo (názov reťazca) {návrat "Hello" + meno; } @Override public void start (kontext BundleContext) vyvolá výnimku {System.out.println ("služba registrácie."); registration = context.registerService (Greeter.class, new GreeterImpl (), new Hashtable ()); referencia = registrácia .getReference (); } @Override public void stop (kontext BundleContext) vyvolá výnimku {System.out.println ("zrušenie registrácie služby."); registration.unregister (); }}

Používame BundleContext ako prostriedok žiadosti o OSGi platformu na registráciu novej inštancie služby.

Mali by sme tiež poskytnúť typ služby a mapu možných konfiguračných parametrov, ktoré v našom jednoduchom scenári nie sú potrebné. Poďme teraz pokračovať v konfigurácii maven-bundle-plugin:

 org.apache.felix maven-bundle-plugin true $ {project.groupId}. $ {project.artifactId} $ {project.artifactId} $ {project.version} com.baeldung.osgi.sample.service.implementation.GreeterImpl com .baeldung.osgi.sample.service.implementácia com.baeldung.osgi.sample.service.definícia 

Stojí za zmienku, že iba com.baeldung.osgi.sample.service.definícia balík bol tentokrát exportovaný cez Exportný balík hlavička.

Vďaka tomu OSGi umožní ostatným balíkom vyvolať iba metódy uvedené v rozhraní služby. Balíček com.baeldung.osgi.sample.service.implementácia je označený ako súkromný, takže žiadny iný balík nebude mať priamy prístup k členom implementácie.

8. Klient OSGi

Poďme teraz napísať klienta. Jednoducho vyhľadá službu pri štarte a vyvolá ju:

klient verejnej triedy implementuje BundleActivator, ServiceListener {}

Poďme implementovať Spustenie BundleActivator () metóda:

privátny BundleContext ctx; private ServiceReference serviceReference; public void start (BundleContext ctx) {this.ctx = ctx; try {ctx.addServiceListener (this, "(objectclass =" + Greeter.class.getName () + ")"); } catch (InvalidSyntaxException ise) {ise.printStackTrace (); }}

The addServiceListener () metóda umožňuje klientovi požiadať platformu o zasielanie oznámení o službe, ktorá je v súlade s poskytnutým výrazom.

Výraz používa syntax podobnú LDAP a v našom prípade požadujeme upozornenia na a Zdravší služby.

Poďme na metódu spätného volania:

public void serviceChanged (ServiceEvent serviceEvent) {int type = serviceEvent.getType (); switch (type) {case (ServiceEvent.REGISTERED): System.out.println ("Oznámenie o zaregistrovaní služby."); serviceReference = serviceEvent .getServiceReference (); Greeter service = (Greeter) (ctx.getService (serviceReference)); System.out.println (service.sayHiTo ("John")); prestávka; prípad (ServiceEvent.UNREGISTERING): System.out.println ("Oznámenie o službe neregistrované."); ctx.ungetService (serviceEvent.getServiceReference ()); prestávka; predvolené: break; }}

Pri niektorých úpravách týkajúcich sa Zdravší služba sa oznámi, spôsob sa oznámi.

Keď je služba zaregistrovaná na platforme, dostaneme na ňu odkaz, uložíme ju lokálne a potom ju použijeme na získanie objektu služby a jeho vyvolanie.

Keď bude server neskôr neregistrovaný, použijeme predtým uložený odkaz na jeho odpojenie, čo znamená, že oznámime platforme, že ho už nebudeme používať.

Teraz už len musíme napísať stop () metóda:

public void stop (BundleContext bundleContext) {if (serviceReference! = null) {ctx.ungetService (serviceReference); }}

Aj tu odpojíme službu, aby sme pokryli prípad, v ktorom je klient zastavený pred zastavením služby. Poďme sa na záver pozrieť na závislosti v pom.xml:

 com.baeldung osgi-intro-sample-service 1.0-SNAPSHOT provided org.osgi org.osgi.core 6.0.0 

9. Klient a služba

Poďme si teraz nainštalovať zväzky klientov a služieb v Karafe vykonaním týchto krokov:

> nainštalovať mvn: com.baeldung / osgi-intro-sample-service / 1.0-SNAPSHOT ID balíka: 64> nainštalovať mvn: com.baeldung / osgi-intro-sample-client / 1.0-SNAPSHOT Bundle ID: 65

Vždy majte na pamäti, že identifikačné čísla pridelené každému balíku sa môžu líšiť.

Začnime teraz balík klientov:

> začiatok 65

Preto sa nič nedeje, pretože klient je aktívny a čaká na službu, s ktorou môžeme začať:

> štart 64 Služba registrácie. Služba zaregistrovaná. Ahoj John

Stane sa to, že akonáhle sa spustí BundleActivator služby, služba je zaregistrovaná na platforme. To následne klienta upozorní, že služba, na ktorú čakal, je k dispozícii.

Klient potom získa odkaz na službu a použije ju na vyvolanie implementácie doručenej prostredníctvom balíka služieb.

10. Záver

V tomto článku sme preskúmali základné vlastnosti OSGi na priamom príklade, ktorý stačí na pochopenie potenciálu OSGi.

Na záver možno povedať, že kedykoľvek musíme zaručiť, že je potrebné aktualizovať jednu aplikáciu bez akejkoľvek služby, môže byť OSGi životaschopným riešením.

Kód tohto príspevku nájdete na GitHub.