SlideShare a Scribd company logo
OSGi meets Lambdas
Safe and powerful interaction with OSGi registry
Carlos Sierra Andrés
Liferay, Inc.
October 2017
Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 1 / 36
What are we going to talk about?
We are going to discuss Aries Component DSL, a PoC library for
interacting with OSGi registry in a functional way.
https://github.com/apache/aries/tree/trunk/component-dsl
Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 2 / 36
Motivation
When creating JAX-RS reference implementation Whiteboard
Dependencies filter depend on configuration.
Dependencies filter depend on incoming services.
Incoming services can specify any number of dependencies on their
properties.
In OSGi this dependencies can come and go at any time.
Also dependencies can be overwritten with higher ranked services at
any time.
Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 3 / 36
bundleContext.registerService(
MyResource.class,
new MyResource(),
new Hashtable<String, Object>() {{
put(
”osgi.jaxrs.application.select”,
”(name=myapplication)”);
put(
”osgi.jaxrs.extension.select”,
new String[] {
”(name=extension1)”,
”(name=extension2)”
});
}});
Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 4 / 36
@Component(
immediate=true,
property={
”osgi.jaxrs.application.select=(name=myapplication)”,
”osgi.jaxrs.extension.select=(name=extension1)”,
”osgi.jaxrs.extension.select=(name=extension2)”,
”osgi.jaxrs.whiteboard.target=(name=special)”
}
service = MyResource.class
public class MyResource {
...
}
Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 5 / 36
Possible implementations
Component Frameworks:
Big runtimes
Difficult to express dependencies programatically based on incoming
services
Plain OSGi API:
ManagedServiceFactories + nested trackers.
Cumbersome to write.
Difficult to reason about.
Difficult to compose and reuse.
Difficult to modify.
Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 6 / 36
bundleContext.registerService(
ManagedServiceFactory.class,
new ManagedServiceFactory() {
public void updated(...) {
new ServiceTracker<>() {
public Object addingService() {
return new ServiceTracker<>() {...}
}
public void removedService() { close }
}
}
public void deleted(String s) { close }
},
new Hashtable<>() {{
put(”service.pid”, ”configuration.pid”);
}}
);
Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 7 / 36
What I would like to have
So I want:
to declare the services and resources I need from the OSGi registry.
to use them when they are ready, and only when they are ready.
the services to clean up their mess when they go away.
to be able to combine them with existing third party classes.
to register new services.
I want dynamism but I DON’T want to deal with it!
Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 8 / 36
Functional Programming to the rescue
Functors: describe computations inside a context.
Monads: express dependency between operations.
Applicative Functors: combine functors with existing functions.
OSGi<T>
Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 9 / 36
Some Primitives
import static OSGi.*;
OSGi<Foo> service = services(Foo.class);
OSGi<ServiceReference<Foo>> sr =
serviceReferences(Foo.class)
OSGi<ServiceRegistration<Foo>> registration =
register(Foo.class, new Foo(), new HashMap<>());
OSGi<Dictionary<String, ?>> c = configurations(”myPid”);
Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 10 / 36
As a functor
Functors allow to express computations in a context
Optional<Object> opt; opt.map(o -> o.toString());
Stream<Integer> numbers; numbers.map(x -> x * 2);
CompletableFuture<String> future; future.map(s -> s + ”; Done!”);
OSGi<Property> p = services.map(s -> s.getProperty());
Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 11 / 36
Prominent Monads (Optional)
Monads allow to express dependent computations
Map<String, String> bigMap1;
Map<String, String> bigMap2;
Map<String, String> bigMap3;
Optional<String> final = Optional.ofNullable(
bigMap.get(”optional1”)
).flatMap(
s1 -> Optional.ofNullable(bigMap2.get(s1))
).flatMap(
s2 -> Optional.ofNullable(bigMap3.get(s2))
)
Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 12 / 36
Prominent Monads (CompletableFuture)
Monads allow to express dependent computations
CompletableFuture<String> heavyTask1() {...};
CompletableFuture<String> heavyTask2() {...};
CompletableFuture<String> heavyTask3(
String param1, String param2) {...};
CompletableFuture<String> future =
heavyTask1().thenCompose(
s1 -> heavyTask2().thenCompose(
s2 -> heavyTask3(s1, s2);
)
);
String result = future.get();
Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 13 / 36
As a monad
Monads allow to express dependent computations
OSGi<ServiceRegistration<POJO>> program =
configurations(”somePid”).flatMap(
cfg ->
services(ServiceA.class, ”(scope=” + cfg.get(”scope”) + ”)”).
flatMap(
sa ->
services(ServiceB.class, sa.getBFilter()).flatMap(
sb ->
register(POJO.class, new POJO(sa, sb), new HashMap<>());
)));
Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 14 / 36
As a monad (normal indentation)
OSGi<ServiceA> serviceAFromConfig(Dictionary<String, ?> cfg) {
return services(
ServiceA.class, ”(scope=” + cfg.get(”scope”) + ”)”);
}
OSGi<ServiceB> serviceBFromServiceA(ServiceA sa) {
return services(ServiceB.class, sa.getBFilter());
}
OSGi<ServiceRegistration<POJO>> program =
configurations(”somePid”).flatMap(
cfg -> serviceAFromConfig(cfg).flatMap(
sa -> serviceBFromServiceA(sa).flatMap(
sb -> register(
POJO.class, new POJO(sa, sb), new HashMap<>())
)));
Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 15 / 36
Prominent Applicatives (CompletableFuture)
Applicatives allow to express computations that don’t depend on
each other
CompletableFuture<String> heavyTask1() {...};
CompletableFuture<String> heavyTask2() {...};
heavyTask1().thenCombine(heavyTask2(), String::concat);
NOTE
We can see that Applicative express that there is no dependency
between heavyTask1 and heavyTask2.
Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 16 / 36
As an Applicative
Applicatives allow to express computations that don’t depend on
each other
public class POJO {
public POJO(ServiceA a, ServiceB b, ServiceC c) {
...
}
}
OSGi<ServiceA> sa = services(ServiceA.class);
OSGi<ServiceB> sb = services(ServiceB.class);
OSGi<ServiceC> sc = services(ServiceC.class);
OSGi<POJO> pojo = OSGi.combine(POJO::new, sa, sb, sc);
it produces the cartesian product of the parameters.
Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 17 / 36
Syntax is a problem
Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 18 / 36
On the bright side
Each step is only executed when there are services or configurations
available.
Effects produced by an instance (service, configuration, etc.) are
associated to it.
When the service or configuration goes away, all the actions triggered
by it are undone by the library.
Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 19 / 36
So in our program
OSGi<ServiceRegistration<POJO>> program =
configurations(”somePid”).flatMap(
cfg -> serviceAFromConfig(cfg).flatMap(
sa -> serviceBFromServiceA(sa).flatMap(
sb -> register(
POJO.class, new Pojo(sa, sb), new HashMap<>())
)));
If any goes away:
Configuration instance
ServiceA instance
ServiceB instance
The corresponding POJO will be unregistered from the OSGi framework
and trackers will be closed.
Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 20 / 36
On the bright side
The expressions in our OSGi language are values in Java. We can
manipulate the values to extend the program:
prepending or appending steps:
public OSGi<?> prependDependency(OSGi<?> program) {
return service(UndisclosedDep.class).then(program);
}
Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 21 / 36
On the bright side
creating conditionals:
public OSGi<ServiceB> chooseService(ServiceReference<?> sr) {
Object filter = sr.getProperty(”filter”);
if (filterProperty != null) {
return services(ServiceB.class, filter.toString());
}
else {
return just(() -> new ServiceB());
}
}
Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 22 / 36
On the bright side
or simply reusing them:
OSGi<ServiceA> sa = services(ServiceA.class);
OSGi<ServiceB> sb = services(ServiceB.class);
OSGi<POJO> pojo = combine(POJO::new, sa, sb);
pojo = prependDependency(pojo);
OSGi<?> program = sa.flatMap(...)
Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 23 / 36
Filtering and replaying
The language also allows to filter and replay already produced events. This
is useful to implement, for instance, highest service filters or highest
service per property filters.
OSGi<ServiceA> sa = service(ServiceA.class).filter(
ServiceA::isEnabled);
OSGi<ServiceReference<ServiceA>> hsa = highest(
serviceReference(ServiceA.class));
OSGi<ServiceReference<ServiceA>> hsProp = highestPer(
serviceReference(ServiceA.class),
sr -> sr.getProperty(”key”));
hsa.flatMap(...)
hsProp.flatMap(...)
Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 24 / 36
Effects handling
The builtin commands make sure they get cleaned when services go away.
But when composing our own commands we might need to interleave
effects when some services are available.
OSGi<ServiceA> program = services(ServiceA.class).effects(
sa -> doSomething(sa),
sa -> undoSomething(sa)
)
OSGi<Void> program = onClose(() -> doSomeCleaning());
Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 25 / 36
Concurrency
The language will make sure that, if an effect has been executed, the
counter effect is also executed. If the effect is never executed the
counter effect is discarded. Althoug effects order is guaranteed by the
monad implementation, counter effects order of execution can’t be
guaranteed.
The implementation is lock free and should be safe to use
concurrently.
Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 26 / 36
Component frameworks
private class MyComponent {
private final Dictionary<String, ?> configuration;
private final Foo mandatory;
private final ArrayList<ServiceForList> servicesForLists;
private ServiceOptional optional = null;
public MyComponent(
Dictionary<String, ?> configuration, Foo mandatory) {
this.configuration = configuration;
this.mandatory = mandatory;
servicesForLists = new ArrayList<>();
}
Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 27 / 36
Component Framework
public Dictionary<String, ?> getConfiguration() {
return configuration;
}
public Foo getMandatory() {
return mandatory;
}
public ServiceOptional getOptional() {
return optional;
}
public ArrayList<ServiceForList> getServiceForLists() {
return _serviceForLists;
}
Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 28 / 36
Component Framework
public void setOptional(ServiceOptional optional) {
this.optional = optional;
}
public void addService(ServiceForList serviceForList) {
_serviceForLists.add(serviceForList);
}
public void removeService(ServiceForList serviceForList) {
_serviceForLists.remove(serviceForList);
}
}
Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 29 / 36
OOP dependency management
Static dependencies are requested in the constructor.
Multiple cardinality dependencies are added and removed through
add/remove methods.
Dynamic dependencies can be added and removed using setters.
Optional properties can be signaled with Optional or null.
No need for @PostConstruct or other lifecycle annotations, when the
class is instantiated it is ready to use.
Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 30 / 36
Component Framework
OSGi<MyComponent> components = combine(
MyComponent::new,
configurations(”org.components.MyComponent”),
services(Foo.class));
OSGi<?> program =
components.flatMap(comp ->
all(
dynamic(
highestService(ServiceOptional.class),
comp::setOptional, c -> comp.setOptional(null)),
dynamic(
services(ServiceForList.class),
comp::addService, comp::removeService),
ignore(register(Component.class, comp, new HashMap<>()))
));
Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 31 / 36
Component Framework
OSGi<MyComponent> components = combine(
MyComponent::new,
configurations(”org.components.MyComponent”),
highestService(services(Foo.class)));
OSGi<?> program =
components.effects(
comp -> comp.setOptional(new ServiceOptional()),
comp -> comp.setOptional(null)
).flatMap(comp -> all(
dynamic(
services(ServiceForList.class),
comp::addService, comp::removeService),
ignore(
register(
Component.class, comp, new HashMap<>()))
));
Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 32 / 36
On the dark side
Did I say syntax is a
problem?!?
Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 33 / 36
On the bright side
It is a thin layer on top of OSGi services API. We have almost all the
power with much fewer code.
Cartesian products and dependent trackers with Stream like API.
Syntax aside, the DSL allows to structure your code like steps of a
script.
No annotations:
So you can reuse existing business classes or use third party classes
directly.
No lifecycle annotation (@PostConstruct) misinteractions
It is embedded in Java:
we get help from the compiler unlike XML based frameworks.
we can create macros or define new functions composing the language
primitives using plain Java functions.
Statements are treated as values, so we can manipulate them and
improve reusability.
Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 34 / 36
Running
OSGi<MyComponent> components = ...
OSGiResult result = components.run(bundleContext);
...
result.close();
To run the described program we only need to provide a valid
bundleContext.
Beware of effects and sharing mutable structures!
Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 35 / 36
?
Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 36 / 36

More Related Content

Similar to OSGi meets Lambdas - C Sierra

It's Java Jim, But Not As We Know It!
It's Java Jim, But Not As We Know It!It's Java Jim, But Not As We Know It!
It's Java Jim, But Not As We Know It!
Simon Ritter
 
Introduction to GraphQL and AWS Appsync on AWS - iOS
Introduction to GraphQL and AWS Appsync on AWS - iOSIntroduction to GraphQL and AWS Appsync on AWS - iOS
Introduction to GraphQL and AWS Appsync on AWS - iOS
Amazon Web Services
 
New and cool in OSGi R7 - David Bosschaert & Carsten Ziegeler
New and cool in OSGi R7 - David Bosschaert & Carsten ZiegelerNew and cool in OSGi R7 - David Bosschaert & Carsten Ziegeler
New and cool in OSGi R7 - David Bosschaert & Carsten Ziegeler
mfrancis
 
NEW LAUNCH! Realtime and Offline application development using GraphQL with A...
NEW LAUNCH! Realtime and Offline application development using GraphQL with A...NEW LAUNCH! Realtime and Offline application development using GraphQL with A...
NEW LAUNCH! Realtime and Offline application development using GraphQL with A...
Amazon Web Services
 
NEW LAUNCH! Realtime and Offline application development using GraphQL with A...
NEW LAUNCH! Realtime and Offline application development using GraphQL with A...NEW LAUNCH! Realtime and Offline application development using GraphQL with A...
NEW LAUNCH! Realtime and Offline application development using GraphQL with A...
Amazon Web Services
 
AppSync and GraphQL on iOS
AppSync and GraphQL on iOSAppSync and GraphQL on iOS
AppSync and GraphQL on iOS
Amazon Web Services
 
It's Java, Jim, but not as we know it
It's Java, Jim, but not as we know itIt's Java, Jim, but not as we know it
It's Java, Jim, but not as we know it
Simon Ritter
 
OSGi R7 - Microservices never looked simpler
OSGi R7 - Microservices never looked simplerOSGi R7 - Microservices never looked simpler
OSGi R7 - Microservices never looked simpler
mfrancis
 
DS, BP, EJB, CDI, WTF!? - Graham Charters
DS, BP, EJB, CDI, WTF!? - Graham ChartersDS, BP, EJB, CDI, WTF!? - Graham Charters
DS, BP, EJB, CDI, WTF!? - Graham Charters
mfrancis
 
GraphQL Meetup Bangkok 3.0
GraphQL Meetup Bangkok 3.0GraphQL Meetup Bangkok 3.0
GraphQL Meetup Bangkok 3.0
Tobias Meixner
 
What's cool in the new and updated OSGi Specs (2013)
What's cool in the new and updated OSGi Specs (2013)What's cool in the new and updated OSGi Specs (2013)
What's cool in the new and updated OSGi Specs (2013)
David Bosschaert
 
Serverless architecture-patterns-and-best-practices
Serverless architecture-patterns-and-best-practicesServerless architecture-patterns-and-best-practices
Serverless architecture-patterns-and-best-practices
saifam
 
OSGi DevCon 2009 Review
OSGi DevCon 2009 ReviewOSGi DevCon 2009 Review
OSGi DevCon 2009 Review
njbartlett
 
20180420 hk-the powerofmysql8
20180420 hk-the powerofmysql820180420 hk-the powerofmysql8
20180420 hk-the powerofmysql8
Ivan Ma
 
JAX RS and CDI bike the reactive bridge
JAX RS and CDI bike the reactive bridgeJAX RS and CDI bike the reactive bridge
JAX RS and CDI bike the reactive bridge
José Paumard
 
JAX-RS and CDI Bike the (Reactive) Bridge
JAX-RS and CDI Bike the (Reactive) BridgeJAX-RS and CDI Bike the (Reactive) Bridge
JAX-RS and CDI Bike the (Reactive) Bridge
José Paumard
 
New Features in JDK 8
New Features in JDK 8New Features in JDK 8
New Features in JDK 8
Martin Toshev
 
Power Saturday 2019 B4 - From relational to Multimodel Azure Cosmos DB
Power Saturday 2019 B4 - From relational to Multimodel Azure Cosmos DBPower Saturday 2019 B4 - From relational to Multimodel Azure Cosmos DB
Power Saturday 2019 B4 - From relational to Multimodel Azure Cosmos DB
PowerSaturdayParis
 
Serverless cat detector workshop - cloudyna 2017 (16.12.2017)
Serverless cat detector   workshop - cloudyna 2017 (16.12.2017)Serverless cat detector   workshop - cloudyna 2017 (16.12.2017)
Serverless cat detector workshop - cloudyna 2017 (16.12.2017)
Paweł Pikuła
 
VBA API for scriptDB primer
VBA API for scriptDB primerVBA API for scriptDB primer
VBA API for scriptDB primer
Bruce McPherson
 

Similar to OSGi meets Lambdas - C Sierra (20)

It's Java Jim, But Not As We Know It!
It's Java Jim, But Not As We Know It!It's Java Jim, But Not As We Know It!
It's Java Jim, But Not As We Know It!
 
Introduction to GraphQL and AWS Appsync on AWS - iOS
Introduction to GraphQL and AWS Appsync on AWS - iOSIntroduction to GraphQL and AWS Appsync on AWS - iOS
Introduction to GraphQL and AWS Appsync on AWS - iOS
 
New and cool in OSGi R7 - David Bosschaert & Carsten Ziegeler
New and cool in OSGi R7 - David Bosschaert & Carsten ZiegelerNew and cool in OSGi R7 - David Bosschaert & Carsten Ziegeler
New and cool in OSGi R7 - David Bosschaert & Carsten Ziegeler
 
NEW LAUNCH! Realtime and Offline application development using GraphQL with A...
NEW LAUNCH! Realtime and Offline application development using GraphQL with A...NEW LAUNCH! Realtime and Offline application development using GraphQL with A...
NEW LAUNCH! Realtime and Offline application development using GraphQL with A...
 
NEW LAUNCH! Realtime and Offline application development using GraphQL with A...
NEW LAUNCH! Realtime and Offline application development using GraphQL with A...NEW LAUNCH! Realtime and Offline application development using GraphQL with A...
NEW LAUNCH! Realtime and Offline application development using GraphQL with A...
 
AppSync and GraphQL on iOS
AppSync and GraphQL on iOSAppSync and GraphQL on iOS
AppSync and GraphQL on iOS
 
It's Java, Jim, but not as we know it
It's Java, Jim, but not as we know itIt's Java, Jim, but not as we know it
It's Java, Jim, but not as we know it
 
OSGi R7 - Microservices never looked simpler
OSGi R7 - Microservices never looked simplerOSGi R7 - Microservices never looked simpler
OSGi R7 - Microservices never looked simpler
 
DS, BP, EJB, CDI, WTF!? - Graham Charters
DS, BP, EJB, CDI, WTF!? - Graham ChartersDS, BP, EJB, CDI, WTF!? - Graham Charters
DS, BP, EJB, CDI, WTF!? - Graham Charters
 
GraphQL Meetup Bangkok 3.0
GraphQL Meetup Bangkok 3.0GraphQL Meetup Bangkok 3.0
GraphQL Meetup Bangkok 3.0
 
What's cool in the new and updated OSGi Specs (2013)
What's cool in the new and updated OSGi Specs (2013)What's cool in the new and updated OSGi Specs (2013)
What's cool in the new and updated OSGi Specs (2013)
 
Serverless architecture-patterns-and-best-practices
Serverless architecture-patterns-and-best-practicesServerless architecture-patterns-and-best-practices
Serverless architecture-patterns-and-best-practices
 
OSGi DevCon 2009 Review
OSGi DevCon 2009 ReviewOSGi DevCon 2009 Review
OSGi DevCon 2009 Review
 
20180420 hk-the powerofmysql8
20180420 hk-the powerofmysql820180420 hk-the powerofmysql8
20180420 hk-the powerofmysql8
 
JAX RS and CDI bike the reactive bridge
JAX RS and CDI bike the reactive bridgeJAX RS and CDI bike the reactive bridge
JAX RS and CDI bike the reactive bridge
 
JAX-RS and CDI Bike the (Reactive) Bridge
JAX-RS and CDI Bike the (Reactive) BridgeJAX-RS and CDI Bike the (Reactive) Bridge
JAX-RS and CDI Bike the (Reactive) Bridge
 
New Features in JDK 8
New Features in JDK 8New Features in JDK 8
New Features in JDK 8
 
Power Saturday 2019 B4 - From relational to Multimodel Azure Cosmos DB
Power Saturday 2019 B4 - From relational to Multimodel Azure Cosmos DBPower Saturday 2019 B4 - From relational to Multimodel Azure Cosmos DB
Power Saturday 2019 B4 - From relational to Multimodel Azure Cosmos DB
 
Serverless cat detector workshop - cloudyna 2017 (16.12.2017)
Serverless cat detector   workshop - cloudyna 2017 (16.12.2017)Serverless cat detector   workshop - cloudyna 2017 (16.12.2017)
Serverless cat detector workshop - cloudyna 2017 (16.12.2017)
 
VBA API for scriptDB primer
VBA API for scriptDB primerVBA API for scriptDB primer
VBA API for scriptDB primer
 

More from mfrancis

Eclipse Modeling Framework and plain OSGi the easy way - Mark Hoffman (Data I...
Eclipse Modeling Framework and plain OSGi the easy way - Mark Hoffman (Data I...Eclipse Modeling Framework and plain OSGi the easy way - Mark Hoffman (Data I...
Eclipse Modeling Framework and plain OSGi the easy way - Mark Hoffman (Data I...
mfrancis
 
OSGi and Java 9+ - BJ Hargrave (IBM)
OSGi and Java 9+ - BJ Hargrave (IBM)OSGi and Java 9+ - BJ Hargrave (IBM)
OSGi and Java 9+ - BJ Hargrave (IBM)
mfrancis
 
Simplify Web UX Coding using OSGi Modularity Magic - Paul Fraser (A2Z Living)
Simplify Web UX Coding using OSGi Modularity Magic - Paul Fraser (A2Z Living)Simplify Web UX Coding using OSGi Modularity Magic - Paul Fraser (A2Z Living)
Simplify Web UX Coding using OSGi Modularity Magic - Paul Fraser (A2Z Living)
mfrancis
 
OSGi for the data centre - Connecting OSGi to Kubernetes - Frank Lyaruu
OSGi for the data centre - Connecting OSGi to Kubernetes - Frank LyaruuOSGi for the data centre - Connecting OSGi to Kubernetes - Frank Lyaruu
OSGi for the data centre - Connecting OSGi to Kubernetes - Frank Lyaruu
mfrancis
 
Remote Management and Monitoring of Distributed OSGi Applications - Tim Verbe...
Remote Management and Monitoring of Distributed OSGi Applications - Tim Verbe...Remote Management and Monitoring of Distributed OSGi Applications - Tim Verbe...
Remote Management and Monitoring of Distributed OSGi Applications - Tim Verbe...
mfrancis
 
OSGi with Docker - a powerful way to develop Java systems - Udo Hafermann (So...
OSGi with Docker - a powerful way to develop Java systems - Udo Hafermann (So...OSGi with Docker - a powerful way to develop Java systems - Udo Hafermann (So...
OSGi with Docker - a powerful way to develop Java systems - Udo Hafermann (So...
mfrancis
 
A real world use case with OSGi R7 - Jurgen Albert (Data In Motion Consulting...
A real world use case with OSGi R7 - Jurgen Albert (Data In Motion Consulting...A real world use case with OSGi R7 - Jurgen Albert (Data In Motion Consulting...
A real world use case with OSGi R7 - Jurgen Albert (Data In Motion Consulting...
mfrancis
 
OSGi Feature Model - Where Art Thou - David Bosschaert (Adobe)
OSGi Feature Model - Where Art Thou - David Bosschaert (Adobe)OSGi Feature Model - Where Art Thou - David Bosschaert (Adobe)
OSGi Feature Model - Where Art Thou - David Bosschaert (Adobe)
mfrancis
 
Migrating from PDE to Bndtools in Practice - Amit Kumar Mondal (Deutsche Tele...
Migrating from PDE to Bndtools in Practice - Amit Kumar Mondal (Deutsche Tele...Migrating from PDE to Bndtools in Practice - Amit Kumar Mondal (Deutsche Tele...
Migrating from PDE to Bndtools in Practice - Amit Kumar Mondal (Deutsche Tele...
mfrancis
 
OSGi CDI Integration Specification - Ray Augé (Liferay)
OSGi CDI Integration Specification - Ray Augé (Liferay)OSGi CDI Integration Specification - Ray Augé (Liferay)
OSGi CDI Integration Specification - Ray Augé (Liferay)
mfrancis
 
How OSGi drives cross-sector energy management - Jörn Tümmler (SMA Solar Tech...
How OSGi drives cross-sector energy management - Jörn Tümmler (SMA Solar Tech...How OSGi drives cross-sector energy management - Jörn Tümmler (SMA Solar Tech...
How OSGi drives cross-sector energy management - Jörn Tümmler (SMA Solar Tech...
mfrancis
 
Improved developer productivity thanks to Maven and OSGi - Lukasz Dywicki (Co...
Improved developer productivity thanks to Maven and OSGi - Lukasz Dywicki (Co...Improved developer productivity thanks to Maven and OSGi - Lukasz Dywicki (Co...
Improved developer productivity thanks to Maven and OSGi - Lukasz Dywicki (Co...
mfrancis
 
It Was Twenty Years Ago Today - Building an OSGi based Smart Home System - Ch...
It Was Twenty Years Ago Today - Building an OSGi based Smart Home System - Ch...It Was Twenty Years Ago Today - Building an OSGi based Smart Home System - Ch...
It Was Twenty Years Ago Today - Building an OSGi based Smart Home System - Ch...
mfrancis
 
Popular patterns revisited on OSGi - Christian Schneider (Adobe)
Popular patterns revisited on OSGi - Christian Schneider (Adobe)Popular patterns revisited on OSGi - Christian Schneider (Adobe)
Popular patterns revisited on OSGi - Christian Schneider (Adobe)
mfrancis
 
Integrating SLF4J and the new OSGi LogService 1.4 - BJ Hargrave (IBM)
Integrating SLF4J and the new OSGi LogService 1.4 - BJ Hargrave (IBM)Integrating SLF4J and the new OSGi LogService 1.4 - BJ Hargrave (IBM)
Integrating SLF4J and the new OSGi LogService 1.4 - BJ Hargrave (IBM)
mfrancis
 
OSG(a)i: because AI needs a runtime - Tim Verbelen (imec)
OSG(a)i: because AI needs a runtime - Tim Verbelen (imec)OSG(a)i: because AI needs a runtime - Tim Verbelen (imec)
OSG(a)i: because AI needs a runtime - Tim Verbelen (imec)
mfrancis
 
Flying to Jupiter with OSGi - Tony Walsh (ESA) & Hristo Indzhov (Telespazio V...
Flying to Jupiter with OSGi - Tony Walsh (ESA) & Hristo Indzhov (Telespazio V...Flying to Jupiter with OSGi - Tony Walsh (ESA) & Hristo Indzhov (Telespazio V...
Flying to Jupiter with OSGi - Tony Walsh (ESA) & Hristo Indzhov (Telespazio V...
mfrancis
 
MicroProfile, OSGi was meant for this - Ray Auge (Liferay)
MicroProfile, OSGi was meant for this - Ray Auge (Liferay)MicroProfile, OSGi was meant for this - Ray Auge (Liferay)
MicroProfile, OSGi was meant for this - Ray Auge (Liferay)
mfrancis
 
Prototyping IoT systems with a hybrid OSGi & Node-RED platform - Bruce Jackso...
Prototyping IoT systems with a hybrid OSGi & Node-RED platform - Bruce Jackso...Prototyping IoT systems with a hybrid OSGi & Node-RED platform - Bruce Jackso...
Prototyping IoT systems with a hybrid OSGi & Node-RED platform - Bruce Jackso...
mfrancis
 
How to connect your OSGi application - Dirk Fauth (Bosch)
How to connect your OSGi application - Dirk Fauth (Bosch)How to connect your OSGi application - Dirk Fauth (Bosch)
How to connect your OSGi application - Dirk Fauth (Bosch)
mfrancis
 

More from mfrancis (20)

Eclipse Modeling Framework and plain OSGi the easy way - Mark Hoffman (Data I...
Eclipse Modeling Framework and plain OSGi the easy way - Mark Hoffman (Data I...Eclipse Modeling Framework and plain OSGi the easy way - Mark Hoffman (Data I...
Eclipse Modeling Framework and plain OSGi the easy way - Mark Hoffman (Data I...
 
OSGi and Java 9+ - BJ Hargrave (IBM)
OSGi and Java 9+ - BJ Hargrave (IBM)OSGi and Java 9+ - BJ Hargrave (IBM)
OSGi and Java 9+ - BJ Hargrave (IBM)
 
Simplify Web UX Coding using OSGi Modularity Magic - Paul Fraser (A2Z Living)
Simplify Web UX Coding using OSGi Modularity Magic - Paul Fraser (A2Z Living)Simplify Web UX Coding using OSGi Modularity Magic - Paul Fraser (A2Z Living)
Simplify Web UX Coding using OSGi Modularity Magic - Paul Fraser (A2Z Living)
 
OSGi for the data centre - Connecting OSGi to Kubernetes - Frank Lyaruu
OSGi for the data centre - Connecting OSGi to Kubernetes - Frank LyaruuOSGi for the data centre - Connecting OSGi to Kubernetes - Frank Lyaruu
OSGi for the data centre - Connecting OSGi to Kubernetes - Frank Lyaruu
 
Remote Management and Monitoring of Distributed OSGi Applications - Tim Verbe...
Remote Management and Monitoring of Distributed OSGi Applications - Tim Verbe...Remote Management and Monitoring of Distributed OSGi Applications - Tim Verbe...
Remote Management and Monitoring of Distributed OSGi Applications - Tim Verbe...
 
OSGi with Docker - a powerful way to develop Java systems - Udo Hafermann (So...
OSGi with Docker - a powerful way to develop Java systems - Udo Hafermann (So...OSGi with Docker - a powerful way to develop Java systems - Udo Hafermann (So...
OSGi with Docker - a powerful way to develop Java systems - Udo Hafermann (So...
 
A real world use case with OSGi R7 - Jurgen Albert (Data In Motion Consulting...
A real world use case with OSGi R7 - Jurgen Albert (Data In Motion Consulting...A real world use case with OSGi R7 - Jurgen Albert (Data In Motion Consulting...
A real world use case with OSGi R7 - Jurgen Albert (Data In Motion Consulting...
 
OSGi Feature Model - Where Art Thou - David Bosschaert (Adobe)
OSGi Feature Model - Where Art Thou - David Bosschaert (Adobe)OSGi Feature Model - Where Art Thou - David Bosschaert (Adobe)
OSGi Feature Model - Where Art Thou - David Bosschaert (Adobe)
 
Migrating from PDE to Bndtools in Practice - Amit Kumar Mondal (Deutsche Tele...
Migrating from PDE to Bndtools in Practice - Amit Kumar Mondal (Deutsche Tele...Migrating from PDE to Bndtools in Practice - Amit Kumar Mondal (Deutsche Tele...
Migrating from PDE to Bndtools in Practice - Amit Kumar Mondal (Deutsche Tele...
 
OSGi CDI Integration Specification - Ray Augé (Liferay)
OSGi CDI Integration Specification - Ray Augé (Liferay)OSGi CDI Integration Specification - Ray Augé (Liferay)
OSGi CDI Integration Specification - Ray Augé (Liferay)
 
How OSGi drives cross-sector energy management - Jörn Tümmler (SMA Solar Tech...
How OSGi drives cross-sector energy management - Jörn Tümmler (SMA Solar Tech...How OSGi drives cross-sector energy management - Jörn Tümmler (SMA Solar Tech...
How OSGi drives cross-sector energy management - Jörn Tümmler (SMA Solar Tech...
 
Improved developer productivity thanks to Maven and OSGi - Lukasz Dywicki (Co...
Improved developer productivity thanks to Maven and OSGi - Lukasz Dywicki (Co...Improved developer productivity thanks to Maven and OSGi - Lukasz Dywicki (Co...
Improved developer productivity thanks to Maven and OSGi - Lukasz Dywicki (Co...
 
It Was Twenty Years Ago Today - Building an OSGi based Smart Home System - Ch...
It Was Twenty Years Ago Today - Building an OSGi based Smart Home System - Ch...It Was Twenty Years Ago Today - Building an OSGi based Smart Home System - Ch...
It Was Twenty Years Ago Today - Building an OSGi based Smart Home System - Ch...
 
Popular patterns revisited on OSGi - Christian Schneider (Adobe)
Popular patterns revisited on OSGi - Christian Schneider (Adobe)Popular patterns revisited on OSGi - Christian Schneider (Adobe)
Popular patterns revisited on OSGi - Christian Schneider (Adobe)
 
Integrating SLF4J and the new OSGi LogService 1.4 - BJ Hargrave (IBM)
Integrating SLF4J and the new OSGi LogService 1.4 - BJ Hargrave (IBM)Integrating SLF4J and the new OSGi LogService 1.4 - BJ Hargrave (IBM)
Integrating SLF4J and the new OSGi LogService 1.4 - BJ Hargrave (IBM)
 
OSG(a)i: because AI needs a runtime - Tim Verbelen (imec)
OSG(a)i: because AI needs a runtime - Tim Verbelen (imec)OSG(a)i: because AI needs a runtime - Tim Verbelen (imec)
OSG(a)i: because AI needs a runtime - Tim Verbelen (imec)
 
Flying to Jupiter with OSGi - Tony Walsh (ESA) & Hristo Indzhov (Telespazio V...
Flying to Jupiter with OSGi - Tony Walsh (ESA) & Hristo Indzhov (Telespazio V...Flying to Jupiter with OSGi - Tony Walsh (ESA) & Hristo Indzhov (Telespazio V...
Flying to Jupiter with OSGi - Tony Walsh (ESA) & Hristo Indzhov (Telespazio V...
 
MicroProfile, OSGi was meant for this - Ray Auge (Liferay)
MicroProfile, OSGi was meant for this - Ray Auge (Liferay)MicroProfile, OSGi was meant for this - Ray Auge (Liferay)
MicroProfile, OSGi was meant for this - Ray Auge (Liferay)
 
Prototyping IoT systems with a hybrid OSGi & Node-RED platform - Bruce Jackso...
Prototyping IoT systems with a hybrid OSGi & Node-RED platform - Bruce Jackso...Prototyping IoT systems with a hybrid OSGi & Node-RED platform - Bruce Jackso...
Prototyping IoT systems with a hybrid OSGi & Node-RED platform - Bruce Jackso...
 
How to connect your OSGi application - Dirk Fauth (Bosch)
How to connect your OSGi application - Dirk Fauth (Bosch)How to connect your OSGi application - Dirk Fauth (Bosch)
How to connect your OSGi application - Dirk Fauth (Bosch)
 

Recently uploaded

Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
KatiaHIMEUR1
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
Laura Byrne
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
Prayukth K V
 
Generating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using SmithyGenerating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using Smithy
g2nightmarescribd
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
Product School
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Jeffrey Haguewood
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
James Anderson
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
Product School
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
Dorra BARTAGUIZ
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Inflectra
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Product School
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
UiPathCommunity
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
91mobiles
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
BookNet Canada
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
ControlCase
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Tobias Schneck
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
Jemma Hussein Allen
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
Guy Korland
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
Elena Simperl
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Ramesh Iyer
 

Recently uploaded (20)

Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
 
Generating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using SmithyGenerating a custom Ruby SDK for your web service or Rails API using Smithy
Generating a custom Ruby SDK for your web service or Rails API using Smithy
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
 

OSGi meets Lambdas - C Sierra

  • 1. OSGi meets Lambdas Safe and powerful interaction with OSGi registry Carlos Sierra Andrés Liferay, Inc. October 2017 Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 1 / 36
  • 2. What are we going to talk about? We are going to discuss Aries Component DSL, a PoC library for interacting with OSGi registry in a functional way. https://github.com/apache/aries/tree/trunk/component-dsl Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 2 / 36
  • 3. Motivation When creating JAX-RS reference implementation Whiteboard Dependencies filter depend on configuration. Dependencies filter depend on incoming services. Incoming services can specify any number of dependencies on their properties. In OSGi this dependencies can come and go at any time. Also dependencies can be overwritten with higher ranked services at any time. Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 3 / 36
  • 4. bundleContext.registerService( MyResource.class, new MyResource(), new Hashtable<String, Object>() {{ put( ”osgi.jaxrs.application.select”, ”(name=myapplication)”); put( ”osgi.jaxrs.extension.select”, new String[] { ”(name=extension1)”, ”(name=extension2)” }); }}); Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 4 / 36
  • 6. Possible implementations Component Frameworks: Big runtimes Difficult to express dependencies programatically based on incoming services Plain OSGi API: ManagedServiceFactories + nested trackers. Cumbersome to write. Difficult to reason about. Difficult to compose and reuse. Difficult to modify. Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 6 / 36
  • 7. bundleContext.registerService( ManagedServiceFactory.class, new ManagedServiceFactory() { public void updated(...) { new ServiceTracker<>() { public Object addingService() { return new ServiceTracker<>() {...} } public void removedService() { close } } } public void deleted(String s) { close } }, new Hashtable<>() {{ put(”service.pid”, ”configuration.pid”); }} ); Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 7 / 36
  • 8. What I would like to have So I want: to declare the services and resources I need from the OSGi registry. to use them when they are ready, and only when they are ready. the services to clean up their mess when they go away. to be able to combine them with existing third party classes. to register new services. I want dynamism but I DON’T want to deal with it! Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 8 / 36
  • 9. Functional Programming to the rescue Functors: describe computations inside a context. Monads: express dependency between operations. Applicative Functors: combine functors with existing functions. OSGi<T> Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 9 / 36
  • 10. Some Primitives import static OSGi.*; OSGi<Foo> service = services(Foo.class); OSGi<ServiceReference<Foo>> sr = serviceReferences(Foo.class) OSGi<ServiceRegistration<Foo>> registration = register(Foo.class, new Foo(), new HashMap<>()); OSGi<Dictionary<String, ?>> c = configurations(”myPid”); Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 10 / 36
  • 11. As a functor Functors allow to express computations in a context Optional<Object> opt; opt.map(o -> o.toString()); Stream<Integer> numbers; numbers.map(x -> x * 2); CompletableFuture<String> future; future.map(s -> s + ”; Done!”); OSGi<Property> p = services.map(s -> s.getProperty()); Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 11 / 36
  • 12. Prominent Monads (Optional) Monads allow to express dependent computations Map<String, String> bigMap1; Map<String, String> bigMap2; Map<String, String> bigMap3; Optional<String> final = Optional.ofNullable( bigMap.get(”optional1”) ).flatMap( s1 -> Optional.ofNullable(bigMap2.get(s1)) ).flatMap( s2 -> Optional.ofNullable(bigMap3.get(s2)) ) Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 12 / 36
  • 13. Prominent Monads (CompletableFuture) Monads allow to express dependent computations CompletableFuture<String> heavyTask1() {...}; CompletableFuture<String> heavyTask2() {...}; CompletableFuture<String> heavyTask3( String param1, String param2) {...}; CompletableFuture<String> future = heavyTask1().thenCompose( s1 -> heavyTask2().thenCompose( s2 -> heavyTask3(s1, s2); ) ); String result = future.get(); Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 13 / 36
  • 14. As a monad Monads allow to express dependent computations OSGi<ServiceRegistration<POJO>> program = configurations(”somePid”).flatMap( cfg -> services(ServiceA.class, ”(scope=” + cfg.get(”scope”) + ”)”). flatMap( sa -> services(ServiceB.class, sa.getBFilter()).flatMap( sb -> register(POJO.class, new POJO(sa, sb), new HashMap<>()); ))); Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 14 / 36
  • 15. As a monad (normal indentation) OSGi<ServiceA> serviceAFromConfig(Dictionary<String, ?> cfg) { return services( ServiceA.class, ”(scope=” + cfg.get(”scope”) + ”)”); } OSGi<ServiceB> serviceBFromServiceA(ServiceA sa) { return services(ServiceB.class, sa.getBFilter()); } OSGi<ServiceRegistration<POJO>> program = configurations(”somePid”).flatMap( cfg -> serviceAFromConfig(cfg).flatMap( sa -> serviceBFromServiceA(sa).flatMap( sb -> register( POJO.class, new POJO(sa, sb), new HashMap<>()) ))); Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 15 / 36
  • 16. Prominent Applicatives (CompletableFuture) Applicatives allow to express computations that don’t depend on each other CompletableFuture<String> heavyTask1() {...}; CompletableFuture<String> heavyTask2() {...}; heavyTask1().thenCombine(heavyTask2(), String::concat); NOTE We can see that Applicative express that there is no dependency between heavyTask1 and heavyTask2. Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 16 / 36
  • 17. As an Applicative Applicatives allow to express computations that don’t depend on each other public class POJO { public POJO(ServiceA a, ServiceB b, ServiceC c) { ... } } OSGi<ServiceA> sa = services(ServiceA.class); OSGi<ServiceB> sb = services(ServiceB.class); OSGi<ServiceC> sc = services(ServiceC.class); OSGi<POJO> pojo = OSGi.combine(POJO::new, sa, sb, sc); it produces the cartesian product of the parameters. Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 17 / 36
  • 18. Syntax is a problem Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 18 / 36
  • 19. On the bright side Each step is only executed when there are services or configurations available. Effects produced by an instance (service, configuration, etc.) are associated to it. When the service or configuration goes away, all the actions triggered by it are undone by the library. Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 19 / 36
  • 20. So in our program OSGi<ServiceRegistration<POJO>> program = configurations(”somePid”).flatMap( cfg -> serviceAFromConfig(cfg).flatMap( sa -> serviceBFromServiceA(sa).flatMap( sb -> register( POJO.class, new Pojo(sa, sb), new HashMap<>()) ))); If any goes away: Configuration instance ServiceA instance ServiceB instance The corresponding POJO will be unregistered from the OSGi framework and trackers will be closed. Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 20 / 36
  • 21. On the bright side The expressions in our OSGi language are values in Java. We can manipulate the values to extend the program: prepending or appending steps: public OSGi<?> prependDependency(OSGi<?> program) { return service(UndisclosedDep.class).then(program); } Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 21 / 36
  • 22. On the bright side creating conditionals: public OSGi<ServiceB> chooseService(ServiceReference<?> sr) { Object filter = sr.getProperty(”filter”); if (filterProperty != null) { return services(ServiceB.class, filter.toString()); } else { return just(() -> new ServiceB()); } } Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 22 / 36
  • 23. On the bright side or simply reusing them: OSGi<ServiceA> sa = services(ServiceA.class); OSGi<ServiceB> sb = services(ServiceB.class); OSGi<POJO> pojo = combine(POJO::new, sa, sb); pojo = prependDependency(pojo); OSGi<?> program = sa.flatMap(...) Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 23 / 36
  • 24. Filtering and replaying The language also allows to filter and replay already produced events. This is useful to implement, for instance, highest service filters or highest service per property filters. OSGi<ServiceA> sa = service(ServiceA.class).filter( ServiceA::isEnabled); OSGi<ServiceReference<ServiceA>> hsa = highest( serviceReference(ServiceA.class)); OSGi<ServiceReference<ServiceA>> hsProp = highestPer( serviceReference(ServiceA.class), sr -> sr.getProperty(”key”)); hsa.flatMap(...) hsProp.flatMap(...) Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 24 / 36
  • 25. Effects handling The builtin commands make sure they get cleaned when services go away. But when composing our own commands we might need to interleave effects when some services are available. OSGi<ServiceA> program = services(ServiceA.class).effects( sa -> doSomething(sa), sa -> undoSomething(sa) ) OSGi<Void> program = onClose(() -> doSomeCleaning()); Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 25 / 36
  • 26. Concurrency The language will make sure that, if an effect has been executed, the counter effect is also executed. If the effect is never executed the counter effect is discarded. Althoug effects order is guaranteed by the monad implementation, counter effects order of execution can’t be guaranteed. The implementation is lock free and should be safe to use concurrently. Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 26 / 36
  • 27. Component frameworks private class MyComponent { private final Dictionary<String, ?> configuration; private final Foo mandatory; private final ArrayList<ServiceForList> servicesForLists; private ServiceOptional optional = null; public MyComponent( Dictionary<String, ?> configuration, Foo mandatory) { this.configuration = configuration; this.mandatory = mandatory; servicesForLists = new ArrayList<>(); } Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 27 / 36
  • 28. Component Framework public Dictionary<String, ?> getConfiguration() { return configuration; } public Foo getMandatory() { return mandatory; } public ServiceOptional getOptional() { return optional; } public ArrayList<ServiceForList> getServiceForLists() { return _serviceForLists; } Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 28 / 36
  • 29. Component Framework public void setOptional(ServiceOptional optional) { this.optional = optional; } public void addService(ServiceForList serviceForList) { _serviceForLists.add(serviceForList); } public void removeService(ServiceForList serviceForList) { _serviceForLists.remove(serviceForList); } } Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 29 / 36
  • 30. OOP dependency management Static dependencies are requested in the constructor. Multiple cardinality dependencies are added and removed through add/remove methods. Dynamic dependencies can be added and removed using setters. Optional properties can be signaled with Optional or null. No need for @PostConstruct or other lifecycle annotations, when the class is instantiated it is ready to use. Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 30 / 36
  • 31. Component Framework OSGi<MyComponent> components = combine( MyComponent::new, configurations(”org.components.MyComponent”), services(Foo.class)); OSGi<?> program = components.flatMap(comp -> all( dynamic( highestService(ServiceOptional.class), comp::setOptional, c -> comp.setOptional(null)), dynamic( services(ServiceForList.class), comp::addService, comp::removeService), ignore(register(Component.class, comp, new HashMap<>())) )); Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 31 / 36
  • 32. Component Framework OSGi<MyComponent> components = combine( MyComponent::new, configurations(”org.components.MyComponent”), highestService(services(Foo.class))); OSGi<?> program = components.effects( comp -> comp.setOptional(new ServiceOptional()), comp -> comp.setOptional(null) ).flatMap(comp -> all( dynamic( services(ServiceForList.class), comp::addService, comp::removeService), ignore( register( Component.class, comp, new HashMap<>())) )); Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 32 / 36
  • 33. On the dark side Did I say syntax is a problem?!? Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 33 / 36
  • 34. On the bright side It is a thin layer on top of OSGi services API. We have almost all the power with much fewer code. Cartesian products and dependent trackers with Stream like API. Syntax aside, the DSL allows to structure your code like steps of a script. No annotations: So you can reuse existing business classes or use third party classes directly. No lifecycle annotation (@PostConstruct) misinteractions It is embedded in Java: we get help from the compiler unlike XML based frameworks. we can create macros or define new functions composing the language primitives using plain Java functions. Statements are treated as values, so we can manipulate them and improve reusability. Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 34 / 36
  • 35. Running OSGi<MyComponent> components = ... OSGiResult result = components.run(bundleContext); ... result.close(); To run the described program we only need to provide a valid bundleContext. Beware of effects and sharing mutable structures! Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 35 / 36
  • 36. ? Carlos Sierra Andrés (Liferay, Inc.) OSGi meets Lambdas October 2017 36 / 36