Introduksjon til OSGi

1. Introduksjon

Flere Java-oppdragskritiske og mellomvareapplikasjoner har noen harde teknologiske krav.

Noen må støtte hot deploy, for ikke å forstyrre tjenestene som kjører - og andre må kunne arbeide med forskjellige versjoner av samme pakke for å støtte eksterne eldre systemer.

De OSGi plattformer representerer en levedyktig løsning for å støtte denne typen krav.

De Åpne Service Gateway Initiative er en spesifikasjon som definerer et Java-basert komponentsystem. Den administreres for øyeblikket av OSGi Alliance, og den første versjonen dateres tilbake til 1999.

Siden da har det vist seg å være en god standard for komponentsystemer, og det er mye brukt i dag. De Formørkelse IDEer for eksempel en OSGi-basert applikasjon.

I denne artikkelen vil vi utforske noen grunnleggende funksjoner i OSGi utnytte implementeringen gitt av Apache.

2. OSGi Basics

I OSGi kalles en enkelt komponent en pakke.

Logisk, en pakke er en funksjonalitet som har en uavhengig livssyklus - som betyr at den kan startes, stoppes og fjernes uavhengig.

Teknisk sett er en pakke bare en jar-fil med en MANIFEST.MF fil som inneholder noen OSGi-spesifikke overskrifter.

De OSGi plattform gir en måte å motta varsler om at pakker blir tilgjengelige eller når de fjernes fra plattformen. Dette vil gjøre det mulig for en riktig designet klient å fortsette å jobbe, kanskje med svekket funksjonalitet, selv når en tjeneste det er avhengig av, ikke er tilgjengelig nå.

På grunn av det må en pakke eksplisitt erklære hvilke pakker den trenger å ha tilgang til og OSGi plattformen vil starte den bare hvis avhengighetene er tilgjengelige i selve pakken eller i andre pakker som allerede er installert i plattformen.

3. Få verktøyene

Vi starter reisen vår OSGi ved å laste ned den siste versjonen av Apache Karaf fra denne lenken. Apache Karaf er en plattform som går OSGi-baserte applikasjoner; den er basert på Apache’S implementering av OSGi spesifikasjon kalt Apache Felix.

Karaf tilbyr noen praktiske funksjoner på toppen av Felix som vil hjelpe oss med å bli kjent med OSGi, for eksempel et kommandolinjegrensesnitt som lar oss samhandle med plattformen.

Å installere Karaf, kan du følge installasjonsinstruksjonene fra den offisielle dokumentasjonen.

4. Pakkeinngang

For å utføre et program i et OSGi-miljø, må vi pakke det som en OSGi pakke og definere programinngangspunktet, og det er ikke vanlig public static void main (String [] args) metode.

Så la oss starte med å bygge en OSGi- basert “Hello World” -applikasjon.

Vi begynner å sette opp en enkel avhengighet av kjernen OSGi API:

 org.osgi org.osgi.core 6.0.0 gitt 

Avhengigheten erklæres som sørget for fordi den vil være tilgjengelig i OSGi kjøretid, og pakken trenger ikke å bygge den inn.

La oss nå skrive det enkle Hei Verden klasse:

offentlig klasse HelloWorld implementerer BundleActivator {public void start (BundleContext ctx) {System.out.println ("Hello world."); } public void stop (BundleContext bundleContext) {System.out.println ("Farvel verden."); }}

BundleActivator er et grensesnitt levert av OSGi som må implementeres av klasser som er inngangspunkter for en pakke.

De start() metoden påberopes av OSGi plattform når pakken som inneholder denne klassen, startes. På den andre siden Stoppe() blir påkalt før like før pakken stoppes.

La oss huske at hver pakke maksimalt kan inneholde en BundleActivator. De BundleContext objektet gitt til begge metodene tillater samhandling med OSGi kjøretid. Vi kommer snart tilbake til det.

5. Å bygge en pakke

La oss endre pom.xml og gjør det til en faktisk OSGi-pakke.

Først og fremst må vi eksplisitt si at vi skal bygge en pakke, ikke en krukke:

bunt

Så utnytter vi maven-bundle-plugin, høflighet av Apache Felix samfunnet, for å pakke Hei Verden klasse som en OSGi bunt:

 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.activator 

I instruksjonsdelen spesifiserer vi verdiene til OSGi overskrifter vi vil ha med i bunns MANIFEST-fil.

Bundle-Activator er det fullt kvalifiserte navnet på BundleActivator implementering som skal brukes til å starte og stoppe pakken, og det refererer til klassen vi nettopp har skrevet.

Privat pakke er ikke et OSGi-overskrift, men det brukes til å fortelle plugin-programmet å inkludere pakken i pakken, men ikke gjøre den tilgjengelig for andre. Vi kan nå bygge pakken med vanlig kommando mvn ren installasjon.

6. Installere og kjøre pakken

La oss begynne Karaf ved å utføre kommandoen:

/ bin / karaf start

hvor er mappen der Karaf er installert. Når ledeteksten fra Karaf konsollen ser ut til at vi kan utføre følgende kommando for å installere pakken:

> pakke: installer mvn: com.baeldung / osgi-intro-sample-activator / 1.0-SNAPSHOT Pakke-ID: 63

Dette instruerer Karaf om å laste pakken fra det lokale Maven-depotet.

Til gjengjeld skriver Karaf ut den numeriske ID-en som er tildelt bunten, avhengig av antall bunter som allerede er installert og kan variere. Pakken er nå nettopp installert, vi kan nå starte den med følgende kommando:

> pakke: start 63 Hello World

"Hello World" vises umiddelbart så snart pakken startes. Vi kan nå stoppe og avinstallere pakken med:

> pakke: stopp 63> pakke: avinstaller 63

"Goodbye World" vises på konsollen, i samsvar med koden i Stoppe() metode.

7. En OSGi-tjeneste

La oss fortsette å skrive en enkel OSGi tjeneste, et grensesnitt som avslører en metode for å hilse på folk:

pakke com.baeldung.osgi.sample.service.definition; offentlig grensesnitt Greeter {public String sayHiTo (String name); }

La oss skrive en implementering av det som er en BundleActivator også, slik at vi kan instansiere tjenesten og registrere den på plattformen når pakken startes:

pakke com.baeldung.osgi.sample.service.implementation; offentlig klasse GreeterImpl implementerer Greeter, BundleActivator {private ServiceReference referanse; privat ServiceRegistration registrering; @Override public String sayHiTo (String name) {return "Hello" + name; } @ Override public void start (BundleContext context) kaster Unntak {System.out.println ("Registreringstjeneste."); registrering = context.registerService (Greeter.class, ny GreeterImpl (), ny Hashtable ()); referanse = registrering .getReference (); } @ Override public void stop (BundleContext context) kaster Unntak {System.out.println ("Unregistring service."); registrering. avregistrere (); }}

Vi bruker BundleContext som et middel for å be om OSGi plattform for å registrere en ny forekomst av tjenesten.

Vi bør også gi tjenestetypen og et kart over de mulige konfigurasjonsparametrene, som ikke er nødvendige i vårt enkle scenario. La oss nå fortsette med konfigurasjonen av maven-pakke-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.implementation com.baeldung.osgi.sample.service.definition 

Det er verdt å merke seg at bare com.baeldung.osgi.sample.service.definition pakken er eksportert denne gangen gjennom Eksport-pakke Overskrift.

Takket være dette, OSGi vil tillate andre bunter å påkalle bare metodene som er spesifisert i tjenestegrensesnittet. Pakke com.baeldung.osgi.sample.service.implementation er merket som privat, så ingen andre pakker vil kunne få tilgang til medlemmene av implementeringen direkte.

8. En OSGi-klient

La oss nå skrive klienten. Det ser ganske enkelt opp tjenesten ved oppstart og påkaller den:

public class Client implementerer BundleActivator, ServiceListener {}

La oss implementere BundleActivator start () metode:

privat BundleContext ctx; private ServiceReference serviceReference; offentlig ugyldig start (BundleContext ctx) {this.ctx = ctx; prøv {ctx.addServiceListener (dette, "(objectclass =" + Greeter.class.getName () + ")"); } catch (InvalidSyntaxException ise) {ise.printStackTrace (); }}

De addServiceListener () metoden lar klienten be plattformen om å sende varsler om tjenesten som oppfyller det angitte uttrykket.

Uttrykket bruker en syntaks som ligner på LDAP, og i vårt tilfelle ber vi om varsler om en Greeter service.

La oss gå videre til tilbakeringingsmetoden:

public void serviceChanged (ServiceEvent serviceEvent) {int type = serviceEvent.getType (); switch (type) {case (ServiceEvent.REGISTERED): System.out.println ("Notification of service registered."); serviceReference = serviceEvent .getServiceReference (); Greeter-tjeneste = (Greeter) (ctx.getService (serviceReference)); System.out.println (service.sayHiTo ("John")); gå i stykker; sak (ServiceEvent.UNREGISTERING): System.out.println ("Melding om tjeneste uregistrert."); ctx.ungetService (serviceEvent.getServiceReference ()); gå i stykker; standard: pause; }}

Når noen modifikasjoner som involverer Greeter tjenesten skjer, blir metoden varslet.

Når tjenesten er registrert på plattformen, får vi en referanse til den, vi lagrer den lokalt, og deretter bruker vi den til å skaffe serviceobjektet og påkalle det.

Når serveren senere er uregistrert, bruker vi den tidligere lagrede referansen til å fjerne den, noe som betyr at vi forteller plattformen at vi ikke kommer til å bruke den lenger.

Vi trenger nå bare å skrive Stoppe() metode:

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

Også her glemmer vi tjenesten for å dekke saken der klienten stoppes før tjenesten stoppes. La oss se på avhengighetene i pom.xml:

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

9. Klient og service

La oss nå installere klient- og servicepakkene i Karaf ved å gjøre:

> install mvn: com.baeldung / osgi-intro-sample-service / 1.0-SNAPSHOT Bundle ID: 64> install mvn: com.baeldung / osgi-intro-sample-client / 1.0-SNAPSHOT Bundle ID: 65

Husk alltid at identifikasjonsnumrene som er tildelt hver pakke, kan variere.

La oss nå starte klientpakken:

> start 65

Derfor skjer ingenting fordi klienten er aktiv og den venter på tjenesten, som vi kan starte med:

> start 64 Registrere tjeneste. Tjeneste registrert. Hei John

Det som skjer er at så snart tjenestens BundleActivator starter, blir tjenesten registrert på plattformen. Dette varsler klienten om at tjenesten den ventet på er tilgjengelig.

Klienten får da en referanse til tjenesten og bruker den til å påkalle implementeringen levert gjennom servicepakken.

10. Konklusjon

I denne artikkelen undersøkte vi de essensielle egenskapene til OSGi med et greit eksempel på at det er nok til å forstå potensialet i OSGi.

Avslutningsvis, når vi må garantere at en enkelt applikasjon må oppdateres uten noen bjørnetjeneste, kan OSGi være en holdbar løsning.

Koden for dette innlegget finner du på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found