Utilizzo di Runtime componente di servizio

L’objective è rimuovere le dipendenze su OSGi dai miei pacchetti. Uso felix (v. 4.2.1) come impl e lo eseguo embeddable. Installare il pacchetto org.apache.felix.scr (v. 1.6.2) per avere il supporto del componente Runtime componente. Ma quando corro

  ServiceReference ref = bundleContext().getServiceReference(ScrService.class.getName()); ScrService s = (ScrService) bundleContext().getService(ref); 

Ricevo ClassCastException: org.apache.felix.scr.impl.ComponentRegistry cannot be cast to org.apache.felix.scr.ScrService .

Va bene. Modificherò i pacchetti di sistema.

 config.put(Constants.FRAMEWORK_SYSTEMPACKAGES, "org.apache.felix.scr"); 

Ora capisco

 Caused by: org.osgi.framework.BundleException: Unresolved constraint in bundle org.apache.felix.scr [1]: Unable to resolve 1.0: missing requirement [1.0] osgi.wiring.package; (&(osgi.wiring.package=org.osgi.framework)(version>=1.4.0)(!(version>=2.0.0))) at org.apache.felix.framework.Felix.resolveBundleRevision(Felix.java:3974) at org.apache.felix.framework.Felix.startBundle(Felix.java:2037) at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:955) at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:942) at com.copyright.rup.communications.felix.Felix.addBundle(Felix.java:86) ... 28 more 

Come posso risolverlo?

Sospetto che il tuo primo blocco in cui cerchi di entrare in ScrService sia sul lato embedding (cioè all’esterno del framework, non all’interno di un bundle installato).

Se questo è il caso, allora hai due copie di ScrService – una caricata dal ClassLoader del tuo codice di incorporamento e una caricata da ClassLoader del pacchetto scr quando viene risolta dal framework. Questo è il motivo per cui stai visualizzando ClassCastException .

Puoi semplicemente esportare le esportazioni del bundle SCR dal bundle framework.

La sezione 3.8, pagina 51 delle specifiche OSGi Core spec v5 afferma che nella risoluzione del cablaggio del bundle se un modulo ha sia le definizioni di importazione che quelle di esportazione dello stesso pacchetto, il framework tenterà prima di risolverlo esternamente e, se avrà esito positivo, eliminerà la definizione di esportazione sovrapposta.

Quindi copia l’intestazione del file Export-Package del pacchetto runtime SCR come proprietà framework:

 properties.put(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA, "org.ops4j.pax.url.mvn,org.apache.felix.scr;uses:=\"org.osgi.framework," + "org.osgi.service.component\";version=\"1.7\"," + "org.apache.felix.scr.component;status=provisional;mandatory:=status;" + "uses:=\"org.osgi.service.component\";version=\"1.0\"," + "org.osgi.service.component;uses:=\"org.osgi.framework\";version=\"1.2\""); //Which you pass to the FrameworkFactory ... ServiceLoader loader = ServiceLoader.load(FrameworkFactory.class); Iterator iterator = loader.iterator(); Framework framework = iterator.next().newFramework(properties); framework.start(); 

Un paio di cose da notare:

  • Se non stai già utilizzando ConfigurationAdmin , installa anche org.osgi.compendium per assicurarti di avere almeno le classi API per org.osgi.service.cm.* E org.osgi.service.metatype* , AFAIK questi sono necessario per il runtime SCR.

  • Non dovresti usare Constants.FRAMEWORK_SYSTEMPACKAGES meno che tu non stia personalizzando seriamente il framework attuale, ma probabilmente vorrai usare Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA per estendere ciò che viene esportato dal framework framework. (Le implementazioni del framework hanno valori predefiniti piuttosto buoni per FRAMEWORK_SYSTEMPACKAGES e di solito non è necessario modificarlo quando si incorpora).