Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Going Native With The OSGi Service Layer - Sascha Zelzer


Published on

OSGi Community Event 2013 (

OSGi is a dynamic module system for Java, supporting the development of highly modular applications. However, many concepts and design choices in the OSGi specifications are language neutral and can, for example, also be applied to native C++ application development. In fact, a vast amount of applications in many different domains (embedded, desktop, server, distributed, etc.) are still written in native languages like C++, for various reasons. In turn, many of these applications are in need of a light-weight modular architecture, fostering a service oriented design to minimize coupling between components and to maximize their re-usability.

The C++ Micro Services project ( is a pure C++ implementation of the OSGi service layer, bringing a dynamic and service oriented framework inspired by OSGi to native application developers. Its scope is similar to the PojoSR project, a Java implementation of the OSGi service layer only. By only implementing the OSGi service layer, the complexity and foot-print of such an implementation is drastically reduced and its usage heavily simplified. Additionally, incrementally modifying an existing project to make use of the OSGi service layer can be viewed as an easy migration path to using a full-blown native OSGi implementation later on.

In this talk, the challenges of mapping the Java OSGi service layer API (based on OSGi R4.3 and Java generics) to an intuitive and easy-to-use C++ API are presented. Further, the properties of the native linkers of the major operating systems (Windows, Linux, MacOS) and how they effectively already implement parts of the OSGi module layer are discussed. These concepts will then be illustrated by looking at how a big C++ toolkit related to medical image processing makes use of the C++ Micro Services project and its OSGi-based service layer implementation. Furthermore, the relationship of the C++ Micro Services project to the recently initiated "Native OSGi" efforts, the related OSGi RFP 156, and other native OSGi implementations like Apache Celix will be discussed.

Sascha Zelzer studied Theoretical Physics in Austria and has been working with Java and C++ for the last ten years. While working on his Ph.D. at the German Cancer Research Center, he is also deeply involved in developing and maintaining a large C++ software stack primarily focused on medical imaging platforms. His current interests include modularized and distributed systems in C++, especially how to leverage the benefits of OSGi technology in a native environment.

Published in: Technology, Education
  • Login to see the comments

Going Native With The OSGi Service Layer - Sascha Zelzer

  1. 1. Going Native with the OSGi Service Layer Sascha Zelzer
  2. 2. About Me ● ● Post-doctoral researcher at the German Cancer Research Center (DKFZ) Interested in – Medical Image Processing and 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
  3. 3. 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
  4. 4. Motivation ● ● ● ● ● Common C++ software toolkit for medical imaging (MITK) Researchers develop their algorithms in shared libraries (modules) High potential for reuse of common services Modularity and interoperability are key points OSGi provides established means to handle modularity and flexibility Sascha Zelzer 29/10/13
  5. 5. 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! Sascha Zelzer 29/10/13
  6. 6. 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 Sascha Zelzer 29/10/13
  7. 7. 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 controlled via meta-data and custom class loaders OSGi takes care of the correct wiring Platform independent: ● Meta-data ● Embedded resources Sascha Zelzer 29/10/13
  8. 8. 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 Sascha Zelzer 29/10/13
  9. 9. 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, …); Sascha Zelzer 29/10/13
  10. 10. 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 support useful throughout the whole code-base! Sascha Zelzer 29/10/13
  11. 11. 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 Sascha Zelzer 29/10/13
  12. 12. C++ Micro Services ● Developed and © German Cancer Research Center ● Is a “OSGi Lite” implementation in C++ ● Apache License 2.0 ● GitHub hosted Sascha Zelzer 29/10/13
  13. 13. 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 a sophisticated program handling ● Dependency resolution ● Symbol versioning ● Library initialization Sascha Zelzer 29/10/13
  14. 14. 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 on link-time dependencies) Less powerful dependency versioning No flat classpath issues as in Java OSGi Lite! Sascha Zelzer 29/10/13
  15. 15. Life Cycle – Dynamic Linker The life-cycle is handled by the dynamic linker too ● ● Sequential state diagram Successfully reaches the ACTIVE state or fails completely ● No lazy activation ● No library updates at runtime ● Activation via static initialization ● Deactivation via static de-initialization ● Life-cycle events available Sascha Zelzer 29/10/13
  16. 16. Service Layer - Templates ● Type-safe templated API – – Any class can be used as a service interface – No custom dynamic_cast calls necessary – ● No base class for service interfaces or service implementations required Pointer magic hidden from the API user API is almost identical to the OSGi specifications Sascha Zelzer 29/10/13
  17. 17. Example – Type Safety ServiceRegistration and ServiceReference classes are templates: struct IMyService { virtual ~IMyService(); }; US_DECLARE_SERVICE_INTERFACE(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(); Sascha Zelzer 29/10/13
  18. 18. 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>(); Sascha Zelzer 29/10/13
  19. 19. Example – Auto Loading Library A struct IMyService {}; Library B Library C struct MyService : public IMyService {}; IMyService* service = ctxt->GetService(...); Loading of Library A triggers auto-loading of associated libraries. Sascha Zelzer 29/10/13
  20. 20. 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) {…} Or any “callable” object (functors, lambdas, etc.) struct MyFunctorialListener { void operator() (const ServiceEvent event) {…} }; context->AddServiceListener(MyFunctorialListener()); Sascha Zelzer 29/10/13
  21. 21. 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; } Sascha Zelzer 29/10/13
  22. 22. 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")); Sascha Zelzer 29/10/13
  23. 23. 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); Sascha Zelzer 29/10/13
  24. 24. 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 ); Sascha Zelzer 29/10/13
  25. 25. More ● Global library specific GetModuleContext() function for easy context retrieval ● Hooks for framework log messages ● Full static linking support Sascha Zelzer 29/10/13
  26. 26. 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) Sascha Zelzer 29/10/13
  27. 27. Use Case - MITK ● Injection of an Activator class in all shared libraries ● Conversion of singletons to services ● Increased cohesion by embedding resources ● ● Decreased coupling via interfaces and services Auto-loading of libraries providing service implementations Sascha Zelzer 29/10/13
  28. 28. Use Case - MITK ● ● ● Whiteboard pattern for interaction event listener Hardware devices (like range cameras and optical tracker) modelled as services File reader writer services with prototype scope Sascha Zelzer 29/10/13
  29. 29. Native OSGi ● Several C/C++ implementations have been created – – CTK Plugin Framework (C++, Qt based) – Apache Celix (C) – Nostrum (C++, POSIX) – SOF (C++, CORBA remoting) – ● CppMicroServices (C++) 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 Sascha Zelzer 29/10/13
  30. 30. 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 Sascha Zelzer 29/10/13
  31. 31. Summary ● OSGi Lite is well accepted by C++ developers ● Less complexity due to the missing module layer ● ● ● ● Less flexibility and dynamism C++ OSGi API can be very close to the Java version Used in and interest from various domains API should converge with Native OSGi efforts in the future Sascha Zelzer 29/10/13
  32. 32. URLs C++ Micro Service ● Homepage ● GitHub ● Blog RFP 156 – Native OSGi ● Bug ● Document Sascha Zelzer 29/10/13
  33. 33. Thank You! Questions? Sascha Zelzer 29/10/13