Transcript
Page 1: Going Native With The OSGi Service Layer - Sascha Zelzer

Going Native with theOSGi Service Layer

Sascha Zelzer

Page 2: Going Native With The OSGi Service Layer - Sascha Zelzer

About Me● Post-doctoral researcher at the German Cancer Research

Center (DKFZ)

● Interested in

– Medical Image Processingand Analysis

– Modularity and interoperability

– Large scale C++ systems

– OSGi technology

● Several years of Java and C++ programming experience

● OSGi Invited Researcher

● Participant in the Native OSGi specification effort

Page 3: Going Native With The OSGi Service Layer - Sascha Zelzer

Outline● Motivation for native OSGi – like frameworks

● Challenges

– Conceptual

– Language● History and Requirements

● The C++ Micro Services Project

– Architecture

– Features● Use Cases

● Excursion: Native OSGi

● Roadmap & Summary

Page 4: Going Native With The OSGi Service Layer - Sascha Zelzer

29/10/13Sascha Zelzer

Motivation● Common C++ software toolkit for medical imaging (MITK)

● Researchers develop their algorithms in shared libraries (modules)

● High potential forreuse of commonservices

● Modularity andinteroperability arekey points

● OSGi providesestablished meansto handle modularityand flexibility

Page 5: Going Native With The OSGi Service Layer - Sascha Zelzer

29/10/13Sascha Zelzer

Motivation

However

● Medical image processing is traditionally done in C++ (Java and Python are gaining popularity)

● Large existing code bases written in C++

● Full blown OSGi framework (even if available for C++) considered too intrusive and heavy-weight

● C/C++ developers are very conservative

● Lack of a migration path towards full OSGi support

Still, there is a need for strong modularity!

Page 6: Going Native With The OSGi Service Layer - Sascha Zelzer

29/10/13Sascha Zelzer

Challenges

OSGi layers are coupled to Java specifics

● Module Layer

– Class loading architecture (visibility of classes)

– Dependency resolution (package wiring)

● Life-cycle Layer

– Lazy activation

– Updates

● Service Layer

– Nothing crucial

● Security Layer

– Based on the Java 2 security architecture

Page 7: Going Native With The OSGi Service Layer - Sascha Zelzer

29/10/13Sascha Zelzer

Conceptual Challenge – Module Layer● Bundles are represented by JAR files with meta-data

● Code is organized in packages

● Bundles export and import Java packages

● Visibility is controlledvia meta-data andcustom class loaders

● OSGi takes care ofthe correct wiring

Platform independent:

● Meta-data

● Embedded resources

Page 8: Going Native With The OSGi Service Layer - Sascha Zelzer

29/10/13Sascha Zelzer

Conceptual Challenge – Life Cycle● Elaborate bundle life-cycle and dependency resolution

● Lazy activation triggered by class loading

● Bundle updates at runtime

Platform independent:

● Activation

● Life-cycle listeners

Page 9: Going Native With The OSGi Service Layer - Sascha Zelzer

29/10/13Sascha Zelzer

Language Challenges● Garbage collector VS Destructors

● Generics VS Templates

● Thread-safety (without third-party libraries)

● Common base class (Object in Java)

ServiceRegistration<?> BundleContext.registerService(java.lang.String clazz, java.lang.Object service, …);

ServiceRegistration<?> BundleContext::registerService(const std::string& clazz, Object* service, …);

Page 10: Going Native With The OSGi Service Layer - Sascha Zelzer

29/10/13Sascha Zelzer

Internal History● The CTK Plugin Framework (started 2007/2008)

– Full C++ OSGi implementation (except Security Layer)

– Qt dependency

● C++ developers like shared libraries, but frameworks not so much

● Full dynamism was rarely needed

● Service registry and bundle activator solved a couple of issues (e.g. dependencies between singletons)

Service registry and basic module layer supportuseful throughout the whole code-base!

Page 11: Going Native With The OSGi Service Layer - Sascha Zelzer

29/10/13Sascha Zelzer

Requirements● No third-party dependencies (only the STL)

● Cross-platform support (Linux, Windows, MacOS)

● C++98 compliance (use C++11 features if available)

● Type-safe API (no void* or client dynamic_cast calls)

● Full Service Layer support

● Module Layer support without its dynamics

Page 12: Going Native With The OSGi Service Layer - Sascha Zelzer

29/10/13Sascha Zelzer

C++ Micro Services

● Developed and © German Cancer Research Center

● Is a “OSGi Lite” implementation in C++

● Apache License 2.0

● GitHub hosted

Page 13: Going Native With The OSGi Service Layer - Sascha Zelzer

29/10/13Sascha Zelzer

C++ Micro Services - Architecture

The CppMicroServices library uses standard shared libraries

● Shared objects (.so) in ELF format on Linux

● Dynamic Link Libraries (.dll) in PE format on Windows

● Dynamic Libraries (.dylib) in MachO format on MacOS

The dynamic linker is asophisticated programhandling

● Dependency resolution

● Symbol versioning

● Library initialization

Page 14: Going Native With The OSGi Service Layer - Sascha Zelzer

29/10/13Sascha Zelzer

Module Layer – Dynamic Linker

The dynamic linker of the OS handles

● Symbol visibility

– GCC / Clang use __attribute__((visibility (“default”))

– MSVC uses__declspec(dllexport)

● Dependency resolution

● Symbol lookup (based onlink-time dependencies)

● Less powerful dependencyversioning

● No flat classpath issues asin Java OSGi Lite!

Page 15: Going Native With The OSGi Service Layer - Sascha Zelzer

29/10/13Sascha Zelzer

Life Cycle – Dynamic Linker

The life-cycle is handled by the dynamiclinker too

● Sequential state diagram

● Successfully reaches the ACTIVEstate or fails completely

● No lazy activation

● No library updates at runtime

● Activation via static initialization

● Deactivation via static de-initialization

● Life-cycle events available

Page 16: Going Native With The OSGi Service Layer - Sascha Zelzer

29/10/13Sascha Zelzer

Service Layer - Templates● Type-safe templated API

– No base class for service interfaces or service implementations required

– Any class can be used as a service interface

– No custom dynamic_cast calls necessary

– Pointer magic hidden from the API user

● API is almost identical to the OSGi specifications

Page 17: Going Native With The OSGi Service Layer - Sascha Zelzer

29/10/13Sascha Zelzer

Example – Type Safety

ServiceRegistration and ServiceReference classes are templates:

struct IMyService { virtual ~IMyService(); };US_DECLARE_SERVICE_INTERFACE(IMyService,"org.me.IMyService")

struct MyService : public IMyService {};MyService myService;ServiceRegistration<IMyService> reg =

context->RegisterService<IMyService>(&myService);

ServiceReference<IMyService> ref = context->GetServiceReference<IMyService>();

IMyService* service = context->GetService(ref);context->UngetService(ref);

reg.Unregister();

Page 18: Going Native With The OSGi Service Layer - Sascha Zelzer

29/10/13Sascha Zelzer

Example – Object Lifetime● Implicitly shared objects

● Almost no raw pointers for library objects in the API

ServiceRegistration<IMyService> reg = context->RegisterService<IMyService>(&myService);

ServiceReference<IMyService> ref =context->GetServiceReference<IMyService>();

Page 19: Going Native With The OSGi Service Layer - Sascha Zelzer

29/10/13Sascha Zelzer

Example – Auto Loading

Loading of Library A triggers auto-loading of associated libraries.

Library A

struct IMyService {};

Library C

IMyService* service =ctxt->GetService(...);

Library B

struct MyService : public IMyService {};

Page 20: Going Native With The OSGi Service Layer - Sascha Zelzer

29/10/13Sascha Zelzer

Example – Listeners● Listeners for library (bundle) events

● Listeners for service events

Use a member function pointer

context->AddServiceListener(this, &MyClass::ServiceChanged);

void ServiceChanged(const ServiceEvent event) {…}

struct MyFunctorialListener { void operator() (const ServiceEvent event) {…}};context->AddServiceListener(MyFunctorialListener());

Or any “callable” object (functors, lambdas, etc.)

Page 21: Going Native With The OSGi Service Layer - Sascha Zelzer

29/10/13Sascha Zelzer

Example - Resources● The generic resources system allows

● Embedding arbitrary data

● Compression if a specific threshold is reached

● Modelling an embedded resources file system

● Access via STL compatible streams

ModuleResource resource = module->GetResource("conf.props");ModuleResourceStream resourceStream(resource);

std::string line;while (std::getline(resourceStream, line)){ std::cout << line << std::endl;}

Page 22: Going Native With The OSGi Service Layer - Sascha Zelzer

29/10/13Sascha Zelzer

Example – JSON Meta-data● Library meta-data can be added via a JSON file

● Embedded as a resource and parsed at load-time

● Arbitrary key-value pairs, accessible via the module API

{"module.version" : "1.0.2","module.description" : "This module provides a service","authors" : [ "John Doe", "Douglas Reynolds", "Daniel Kim" ],"rating" : 5}

Module* module = context->GetModule();int r = ref_any_cast<int>(module->GetProperty("rating"));

Page 23: Going Native With The OSGi Service Layer - Sascha Zelzer

29/10/13Sascha Zelzer

Example – RFC 195 Service Scopes● In OSGi, services are singletons (sharing state) or bundle

specific (ServiceFactory)

● RFC 195 formalizes service scopes

– Singleton and Bundle Scope: As usual

– Prototype Scope (new): Create service instances based on a prototype on demand

class MyFactory : public PrototypeServiceFactory {…};context->RegisterService<IMyService>(myFactory);

ServiceReference<IMyService> ref =context->GetServiceReference<IMyService>();

ServiceObjects<IMyService> objects =context->GetServiceObjects(ref);

IMyService* myService = objects.GetService();objects.UngetService(myService);

Page 24: Going Native With The OSGi Service Layer - Sascha Zelzer

29/10/13Sascha Zelzer

Example – LDAP Filter DSL

Creating LDAP filter strings in Java is error-prone.

Filter example: “(&(name=Ben)(!(count=1)))”

context.createFilter("(&(name=Ben)(!(count=1))");

LDAPFilter filter( LDAPProp("name") == "Ben" && LDAPProp("count") != 1);

Page 25: Going Native With The OSGi Service Layer - Sascha Zelzer

29/10/13Sascha Zelzer

More

● Global library specific GetModuleContext() function for easy context retrieval

● Hooks for framework log messages

● Full static linking support

Page 26: Going Native With The OSGi Service Layer - Sascha Zelzer

29/10/13Sascha Zelzer

Use Cases

DS4Cpp

● A declarative services framework in C++ based on CppMicroServices

● Contributed by Global Vision Systems

● Introduces similar dependency-injection patterns across their Java and C++ code-base

Interest from various technical companies

● Embedded systems

● Avionics and sensoring

● Military sub-contractors working on mission-critical software

● Medical Imaging (e.g. Mint Medical)

Page 27: Going Native With The OSGi Service Layer - Sascha Zelzer

29/10/13Sascha Zelzer

Use Case - MITK● Injection of an Activator class in all shared libraries

● Conversion of singletons to services

● Increased cohesion by embedding resources

● Decreased couplingvia interfaces andservices

● Auto-loading oflibraries providingserviceimplementations

Page 28: Going Native With The OSGi Service Layer - Sascha Zelzer

29/10/13Sascha Zelzer

Use Case - MITK● Whiteboard pattern for interaction event listener

● Hardware devices (like range cameras and optical tracker) modelled as services

● File reader writerservices withprototype scope

Page 29: Going Native With The OSGi Service Layer - Sascha Zelzer

29/10/13Sascha Zelzer

Native OSGi● Several C/C++ implementations have been created

– CppMicroServices (C++)

– CTK Plugin Framework (C++, Qt based)

– Apache Celix (C)

– Nostrum (C++, POSIX)

– SOF (C++, CORBA remoting)

– Poco OSP (commercial)

● Developers joined forces and created RFP 156 Native OSGi for standardization of a native C/C++ API

– RFP 156 will be voted on in November

– RFC workis about to be started

– CppMicroServices is field-testing a native service-layer API

Page 30: Going Native With The OSGi Service Layer - Sascha Zelzer

29/10/13Sascha Zelzer

Roadmap

Release 2.0

● Service hooks

Ecosystem

● Configuration Admin

● Device Access

● Event Admin

● Remote Services

Native OSGi

● Specify the Service Layer API

● Work on a native Module Layer

Page 31: Going Native With The OSGi Service Layer - Sascha Zelzer

29/10/13Sascha Zelzer

Summary● OSGi Lite is well accepted by C++ developers

● Less complexity due to the missing module layer

● Less flexibility anddynamism

● C++ OSGi APIcan be very closeto the Java version

● Used in andinterest fromvarious domains

● API should convergewith Native OSGiefforts in the future

Page 32: Going Native With The OSGi Service Layer - Sascha Zelzer

29/10/13Sascha Zelzer

URLs

C++ Micro Service

● Homepage http://cppmicroservices.org

● GitHub https://github.com/saschazelzer/CppMicroServices

● Blog http://blog.cppmicroservices.org

RFP 156 – Native OSGi

● Bug https://www.osgi.org/bugzilla/show_bug.cgi?id=165

● Document https://github.com/osgi/design/tree/master/rfps

Page 33: Going Native With The OSGi Service Layer - Sascha Zelzer

29/10/13Sascha Zelzer

Thank You!

Questions?


Top Related