going native with the osgi service layer - sascha zelzer

33
Going Native with the OSGi Service Layer Sascha Zelzer

Upload: mfrancis

Post on 28-May-2015

6.664 views

Category:

Technology


4 download

DESCRIPTION

OSGi Community Event 2013 (http://www.osgi.org/CommunityEvent2013/Schedule) ABSTRACT 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 (http://cppmicroservices.org) 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. SPEAKER BIO 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.

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?