Introduktion til OSGi

1. Introduktion

Flere Java-missionskritiske og middleware-applikationer har nogle hårde teknologiske krav.

Nogle er nødt til at understøtte hot deployering for ikke at forstyrre de kørende tjenester - og andre skal kunne arbejde med forskellige versioner af den samme pakke for at understøtte eksterne ældre systemer.

Det OSGi platforme repræsenterer en levedygtig løsning til at understøtte denne type krav.

Det Åbn Service Gateway Initiative er en specifikation, der definerer et Java-baseret komponentsystem. Det administreres i øjeblikket af OSGi Alliance, og dens første version går tilbage til 1999.

Siden da har det vist sig at være en god standard for komponentsystemer, og det er meget brugt i dag. Det Formørkelse IDEer for eksempel en OSGi-baseret applikation.

I denne artikel undersøger vi nogle grundlæggende funktioner i OSGi udnytte implementeringen leveret af Apache.

2. Grundlæggende om OSGi

I OSGi kaldes en enkelt komponent et bundt.

Logisk set et bundt er et stykke funktionalitet, der har en uafhængig livscyklus - hvilket betyder, at det kan startes, stoppes og fjernes uafhængigt.

Teknisk set er et bundt kun en jar-fil med en MANIFEST.MF fil, der indeholder nogle OSGi-specifikke overskrifter.

Det OSGi platform giver en måde at modtage meddelelser om, at bundter bliver tilgængelige, eller når de fjernes fra platformen. Dette gør det muligt for en korrekt designet klient at fortsætte med at arbejde, måske med forringet funktionalitet, selv når en tjeneste, det afhænger af, ikke er tilgængelig.

På grund af dette skal et bundt udtrykkeligt erklære, hvilke pakker det skal have adgang til og OSGi platform vil kun starte det, hvis afhængighederne er tilgængelige i selve pakken eller i andre bundter, der allerede er installeret på platformen.

3. Sådan får du værktøjet

Vi starter vores rejse i OSGi ved at downloade den nyeste version af Apache Karaf fra dette link. Apache Karaf er en platform, der kører OSGi-baserede applikationer; det er baseret på Apache'S implementering af OSGi specifikation kaldet Apache Felix.

Karaf tilbyder nogle praktiske funktioner oven på Felix det vil hjælpe os med at stifte bekendtskab med OSGifor eksempel en kommandolinjegrænseflade, der giver os mulighed for at interagere med platformen.

At installere Karaf, kan du følge installationsvejledningen fra den officielle dokumentation.

4. Bundtindgangssted

For at udføre en applikation i et OSGi-miljø er vi nødt til at pakke den som en OSGi bundt og definer applikationsindgangspunktet, og det er ikke det sædvanlige offentlig statisk ugyldig hoved (String [] args) metode.

Så lad os starte med at bygge en OSGi- baseret “Hello World” -applikation.

Vi begynder at oprette en simpel afhængighed af kernen OSGi API:

 org.osgi org.osgi.core 6.0.0 leveret 

Afhængigheden erklæres som stillet til rådighed fordi det vil være tilgængeligt i OSGi runtime, og pakken behøver ikke at integrere den.

Lad os nu skrive det enkle Hej 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 en grænseflade, der leveres af OSGi der skal implementeres af klasser, der er indgangspunkter for en pakke.

Det Start() metoden påberåbes af OSGi platform, når pakken, der indeholder denne klasse, startes. På den anden side hold op() påberåbes før lige før pakken stoppes.

Lad os huske på, at hver pakke højst kan indeholde en BundleActivator. Det BundleContext objekt leveret til begge metoder tillader interaktion med OSGi runtime. Vi vender snart tilbage til det.

5. Opbygning af en pakke

Lad os ændre pom.xml og gør det til et faktisk OSGi-bundt.

Først og fremmest skal vi udtrykkeligt angive, at vi skal bygge et bundt, ikke en krukke:

bundt

Så udnytter vi maven-bundle-plugin, høflighed af Apache Felix samfund, at pakke Hej Verden klasse som en OSGi bundt:

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

I instruktionssektionen specificerer vi værdierne for OSGi overskrifter, vi vil medtage i bundtets MANIFEST-fil.

Bundle-aktivator er det fuldt kvalificerede navn på BundleActivator implementering, der vil blive brugt til at starte og stoppe bundtet, og det refererer til den klasse, vi lige har skrevet.

Privat pakke er ikke et OSGi-header, men det bruges til at fortælle pluginet at medtage pakken i pakken, men ikke gøre den tilgængelig for andre. Vi kan nu bygge pakken med den sædvanlige kommando mvn ren installation.

6. Installation og kørsel af pakken

Lad os begynde Karaf ved at udføre kommandoen:

/ bin / karaf start

hvor er mappen hvor Karaf er installeret. Når anmodningen fra Karaf konsol vises, vi kan udføre følgende kommando for at installere pakken:

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

Dette instruerer Karaf om at indlæse bundtet fra det lokale Maven-arkiv.

Til gengæld udskriver Karaf det numeriske ID, der er tildelt pakken, der afhænger af antallet af allerede installerede bundter og kan variere. Pakken er nu lige installeret, vi kan nu starte den med følgende kommando:

> bundt: start 63 Hello World

"Hello World" vises straks, så snart bundtet startes. Vi kan nu stoppe og afinstallere pakken med:

> pakke: stop 63> pakke: afinstallere 63

"Farvel verden" vises på konsollen i overensstemmelse med koden i hold op() metode.

7. En OSGi-tjeneste

Lad os fortsætte med at skrive en simpel OSGi service, en grænseflade, der afslører en metode til hilsen på folk:

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

Lad os skrive en implementering af det, der er en BundleActivator også, så vi vil være i stand til at instantiere tjenesten og registrere den på platformen, når pakken startes:

pakke com.baeldung.osgi.sample.service.implementation; offentlig klasse GreeterImpl implementerer Greeter, BundleActivator {privat ServiceReference reference; privat registrering af ServiceRegistration; @ Override public String sayHiTo (String name) {return "Hello" + name; } @ Override offentlig ugyldig start (BundleContext-kontekst) kaster Undtagelse {System.out.println ("Registreringstjeneste."); registrering = context.registerService (Greeter.class, ny GreeterImpl (), ny Hashtable ()); reference = registrering .getReference (); } @ Overstyr offentlig ugyldigt stop (BundleContext-kontekst) kaster undtagelse {System.out.println ("Afmeld tjeneste."); registrering. afmelding (); }}

Vi bruger BundleContext som et middel til at anmode om OSGi platform til at registrere en ny forekomst af tjenesten.

Vi skal også angive tjenestens type og et kort over de mulige konfigurationsparametre, som ikke er nødvendige i vores enkle scenario. Lad os nu gå videre med konfigurationen af maven-bundle-plugin:

 org.apache.felix maven-bundle-plugin sand $ {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 værd at bemærke, at kun den com.baeldung.osgi.sample.service.definition pakken er blevet eksporteret denne gang gennem Eksport-pakke header.

Tak til dette, OSGi tillader, at andre bundter kun påberåber sig de metoder, der er angivet i servicegrænsefladen. Pakke com.baeldung.osgi.sample.service.implementation er markeret som privat, så ingen andre pakker vil kunne få adgang til medlemmerne af implementeringen direkte.

8. En OSGi-klient

Lad os nu skrive klienten. Det ser simpelthen op på tjenesten ved opstart og påberåber den:

public class Client implementerer BundleActivator, ServiceListener {}

Lad os implementere BundleActivator start () metode:

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

Det addServiceListener () metode giver klienten mulighed for at bede platformen om at sende meddelelser om den service, der overholder det angivne udtryk.

Udtrykket bruger en syntaks svarende til LDAP's, og i vores tilfælde anmoder vi om meddelelser om en Greeter service.

Lad os gå videre til tilbagekaldsmetoden:

public void serviceChanged (ServiceEvent serviceEvent) {int type = serviceEvent.getType (); switch (type) {case (ServiceEvent.REGISTERED): System.out.println ("Meddelelse om service registreret."); serviceReference = serviceEvent .getServiceReference (); Greeter service = (Greeter) (ctx.getService (serviceReference)); System.out.println (service.sayHiTo ("John")); pause; sag (ServiceEvent.UNREGISTERING): System.out.println ("Meddelelse om service uregistreret."); ctx.ungetService (serviceEvent.getServiceReference ()); pause; standard: pause; }}

Når nogle ændringer, der involverer Greeter tjenesten sker, meddeles metoden.

Når tjenesten er registreret på platformen, får vi en henvisning til den, vi gemmer den lokalt, og vi bruger den derefter til at erhverve serviceobjektet og påkalde det.

Når serveren senere afregistreres, bruger vi den tidligere gemte reference til at fjerne den, hvilket betyder, at vi fortæller platformen, at vi ikke længere vil bruge den.

Vi skal nu bare skrive hold op() metode:

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

Også her glemmer vi tjenesten for at dække den sag, hvor klienten stoppes, før tjenesten stoppes. Lad os se et sidste kig på afhængighederne i pom.xml:

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

9. Klient og service

Lad os nu installere klient- og servicebundterne i Karaf ved at gøre:

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

Husk altid, at identifikationsnumrene, der er tildelt hver pakke, kan variere.

Lad os nu starte klientpakken:

> start 65

Derfor sker der intet, fordi klienten er aktiv, og den venter på tjenesten, som vi kan starte med:

> start 64 Registrering af service. Service registreret. Hej John

Hvad der sker er, at så snart tjenestens BundleActivator starter, registreres tjenesten på platformen. Dette underretter igen klienten om, at den service, den ventede på, er tilgængelig.

Klienten får derefter en henvisning til tjenesten og bruger den til at påkalde den implementering, der leveres gennem servicepakken.

10. Konklusion

I denne artikel undersøgte vi de væsentlige funktioner i OSGi med et ligetil eksempel, at det er nok til at forstå OSGi's potentiale.

Afslutningsvis, når vi skal garantere, at en enkelt applikation skal opdateres uden nogen bortset tjeneste, kan OSGi være en levedygtig løsning.

Koden til dette indlæg kan findes på GitHub.


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