ERLEDIGT
NEIN
NEIN
ANTWORTEN
0
0
ZUGRIFFE
1533
1533
EMPFEHLEN
-
13.02.10 16:19 #1
- Registriert seit
- Jun 2002
- Ort
- Saarbrücken (Saarland)
- Beiträge
- 9.886
- Blog-Einträge
- 29
Hallo,
die OSGi Plattform bietet mit den OSGi Services eine Möglichkeit Service Komponenten dynamisch abfragen und registrieren zu können.
Dies kann entweder programmatisch (mit BundleContext.registerService, ServiceReference, ServiceTracker) oder deklarativ
über sogenannte Declarative Services geschehen.
Will man über den programmatischen Weg einen Service binden so ist das wegen der dynamischen Natur der OSGi Umgebung
(Bundles die Services bereitstellen können im laufenden Betrieb gestoppt / neugestartet werden) etwas aufwendiger siehe:
http://www.tutorials.de/forum/java/2...n-equinox.html
http://www.tutorials.de/forum/java/3...i-equinox.html
Hier eine Liste zu Standard OSGi Services (für Equinox):
http://www.eclipse.org/equinox/bundl...bundleprojects
Hier mal ein kleines Beispiel wie man mit dynamischen Services in einer OSGi Umgebung arbeiten kann.
Dabei wird für die Arbeit mit dem Service ein ServiceCallback definiert. Über den generischen Typ des ServiceCallbacks
wird dann die entsprechende Service ermittelt welcher für den Aufruf verwendet werden soll.
Die wichtigsten Methoden des ServiceCallback sind runWith(...) und runWithServiceUnavailable().
runWith(...) wird Aufgerufen wenn der verlangte Service zur Verfügung steht andernfalls wird
runWithServiceUnvailable() aufgerufen.
Code java:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
package de.tutorials.osgi.training; import org.osgi.framework.BundleContext; public abstract class ServiceCallback<TService> { abstract void runWith(TService service); protected void runWithServiceUnavailable(){ //default noop } protected BundleContext getBundleContext(){ return null; } protected boolean shouldUngetServiceAfterUse(){ return false; } }
Zu Demonstrationszwecken nehmen wir hier als Beispiel-Service den EventAdmin-Service:
Code java:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
package de.tutorials.osgi.training; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.service.event.EventAdmin; public class Activator implements BundleActivator { private ServiceTrackers serviceTrackers; public void start(final BundleContext context) throws Exception { serviceTrackers = new ServiceTrackers(context); log("starting " + context.getBundle().getSymbolicName()); serviceTrackers.execute(new ServiceCallback<EventAdmin>() { protected void runWith(EventAdmin service) { log("Service is available: " + service); } protected void runWithServiceUnavailable() { log("Service is unavailable: let's do something else..."); } }); } public void log(final String message) { System.out.println("Log: " + message); } public void stop(BundleContext context) throws Exception { log("stopping " + context.getBundle().getSymbolicName()); serviceTrackers.close(); serviceTrackers = null; } }
Unser "Workhorse" ServiceTrackers erledigt nun das verwalten der Service Referenzen / Trackers umd kümmert sich um den Aufruf
der passenden Methode am ServiceCallback.
Code java:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
package de.tutorials.osgi.training; import java.lang.reflect.ParameterizedType; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import org.osgi.framework.BundleContext; import org.osgi.util.tracker.ServiceTracker; public class ServiceTrackers { private BundleContext context; private ConcurrentMap<String, ServiceTracker> cachedTrackers; public ServiceTrackers(BundleContext context) { this.context = context; this.cachedTrackers = new ConcurrentHashMap<String, ServiceTracker>(); } public <TService> void execute(ServiceCallback<TService> serviceCallback) { BundleContext bundleContext = extractBundleContext(serviceCallback); Class<?> serviceClass = extractServiceClass(serviceCallback); String serviceName = serviceClass.getName(); ServiceTracker tracker = getCachedTracker(bundleContext, serviceName); @SuppressWarnings("unchecked") TService service = (TService) tracker.getService(); if (service != null) { serviceCallback.runWith(service); } else { serviceCallback.runWithServiceUnavailable(); } if (serviceCallback.shouldUngetServiceAfterUse()) { tracker = cachedTrackers.remove(serviceName); tracker.close(); } } protected <TService> BundleContext extractBundleContext(ServiceCallback<TService> serviceCallback){ BundleContext bundleContext = serviceCallback.getBundleContext(); if (bundleContext == null) { bundleContext = this.context; } return bundleContext; } protected ServiceTracker getCachedTracker(BundleContext bundleContext, String serviceName) { ServiceTracker tracker = null; if (cachedTrackers.containsKey(serviceName)) { tracker = cachedTrackers.get(serviceName); } else { tracker = new ServiceTracker(bundleContext, serviceName, null); ServiceTracker existingTracker = cachedTrackers.putIfAbsent(serviceName, tracker); if (existingTracker != null) { tracker = existingTracker; } tracker.open(); } return tracker; } protected Class<?> extractServiceClass(ServiceCallback<?> serviceCallback) { ParameterizedType parameterizedType = (ParameterizedType) serviceCallback.getClass().getGenericSuperclass(); Class<?> typeArgument = (Class<?>) parameterizedType.getActualTypeArguments()[0]; return typeArgument; } public void close() { Set<Map.Entry<String, ServiceTracker>> trackers = new HashSet<Map.Entry<String, ServiceTracker>>(cachedTrackers.entrySet()); for (Map.Entry<String, ServiceTracker> serviceNameTracker : trackers) { String serviceName = serviceNameTracker.getKey(); ServiceTracker tracker = serviceNameTracker.getValue(); //log debug: //closing tracker for serviceName in bundleContext tracker.close(); } cachedTrackers.clear(); cachedTrackers = null; } }
Hier mal eine Beispiel-Session:
Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
osgi> Log: starting de.tutorials.osgi.training Log: Service is available: org.eclipse.equinox.internal.event.EventComponent@3b75078b osgi> ss Framework is launched. id State Bundle 0 ACTIVE org.eclipse.osgi_3.6.0.v20100128-1430 2 ACTIVE org.eclipse.osgi.util_3.2.100.v20100108 3 ACTIVE org.eclipse.osgi.services_3.2.100.v20100108 5 ACTIVE org.eclipse.equinox.event_1.2.0.v20100108 8 ACTIVE de.tutorials.osgi.training_1.0.0.qualifier osgi> stop 5 osgi> refresh 8 osgi> Log: stopping de.tutorials.osgi.training Log: starting de.tutorials.osgi.training Log: Service is unavailable: let's do something else... osgi> start 5 osgi> refresh 8 osgi> Log: stopping de.tutorials.osgi.training Log: starting de.tutorials.osgi.training Log: Service is available: org.eclipse.equinox.internal.event.EventComponent@56609959
Gruß TomJava rocks!
How to become a good Java Programmer?
Does IT in Java and .Net
The only valid measurement of code quality: WTFs / minute
Blog
Xing
Twitter
Ähnliche Themen
-
Beispiel für Springframework / Hibernate / Equinox / OSGi / Eclipse / ExtensionPoints
Von Thomas Darimont im Forum JavaAntworten: 5Letzter Beitrag: 06.11.08, 19:21 -
Synth und OSGi (Equinox) Frage
Von daywalkertp im Forum JavaAntworten: 1Letzter Beitrag: 21.04.08, 16:15 -
Videotutorials zu Eclipse Equinox OSGi Runtime
Von Thomas Darimont im Forum Java Technology NewsAntworten: 0Letzter Beitrag: 15.01.08, 17:14 -
Interessanter Vergleich zwischen Eclipse Extensions und OSGi Services
Von Thomas Darimont im Forum Java Technology NewsAntworten: 0Letzter Beitrag: 27.04.07, 13:56 -
Beispiel für die Verwendung von OSGi Services auf Basis von Equinox
Von Thomas Darimont im Forum JavaAntworten: 0Letzter Beitrag: 17.03.07, 15:00






Zitieren
Login





