SlideShare une entreprise Scribd logo
1  sur  106
Télécharger pour lire hors ligne
June 10-11, 2008 Berlin, Germany
iPOJO: The Simple Life
Richard S. Hall
2
Agenda
• Introduction & Background
• iPOJO Overview
• The Basics
• Providing Services
• Using Services
• Configuring Instances
• Creating Composites
• Conclusion
3
Introduction
& Background
4
Introduction
• OSGi technology provides an interesting platform for
creating dynamically extensible applications
• However, dealing with dynamism is a pain...
• ...raising the abstraction is necessary
• Developers should concentrate on application logic, not
low-level OSGi mechanisms
• Solving these issues is necessary if we want to
move into innovative areas
• Context awareness, pervasive computing, autonomic
computing, etc.
5
Background
• I started implementing the OSGi specification so that
I could investigate dynamic assembly of applications
• The framework was called Oscar
• Unfortunately, I have not stopped implementing it
2000
6
Background
• Humberto Cervantes and I started to discuss OSGi
component models
• Humberto finished a prototype of Beanome in 2002
• Defined a simple OSGi-based component model with factories and
simple service dependency management
2001
7
Background
• Humberto and I started working on a general
approach to simplify OSGi dynamic service
dependency management
• Humberto developed Service Binder as part of his PhD
• Included all of the standard mechanisms (e.g., optionality,
aggregation, binding policies, etc.)
2002
8
Background
• Declarative Services was being defined,
incorporating ideas from Service Binder
• Experimental versions of Service Binder introduced
a composite service model
• However, it proved insufficient
2004
9
Background
• I started thinking about an improved way to create
composite services using byte code generation
• Peter Kriens starts thinking about using byte code
manipulation to further simplify (de-cruft) dynamic
dependency management
• Peter gets into the details and presents a prototype in
October 2005
2005
10
Background
• Around 2006, Clement Escoffier and I started
working together to create iPOJO
• Combine Peter's “de-crufting” effort with the ability to
create dynamic composite services
• Clement does all of the hard work, I just complain about it
• Which leads us to now...
2006
11
iPOJO Overview
12
iPOJO Overview
• Approach
• Make things simple
• Simple things should be simple
• Not so simple things should still be reasonably simple
• Complicated things should be possible
• Follow POJO philosophy
• Use plain old Java objects
• Avoid tying application logic to component framework
• Employ byte code manipulation techniques
• Intercept access to component member fields
• Monitor component method entry, exit, and exceptions
• Be as lazy as possible
13
iPOJO Overview
• Usage
• Part of the build process, specifically packaging
• First, compile component source
• Then, package component as bundle (perhaps using BND)
• Finally, process bundle with iPOJO manipulator
• Supports Maven, Ant, and Eclipse
• Example Ant task definition:
<target name=”post-package” depends=”package”>
<ipojo input="${output.dir}/${project.name}.jar"
metadata="metadata.xml"/>
</target>
14
iPOJO Overview
• Issues
• POJO-ness
• iPOJO does not support constructor injection
• Possible, but it is anathema to dynamism
• iPOJO requires an empty constructor or a constructor with bundle
context argument
• Service dependencies are usable in the constructor
• Possible to have constructor with other arguments, but iPOJO will not
use it
• iPOJO supports annotations
• The examples in this presentation use annotations
• However, annotations are still a form of API and reduce POJO-ness
• iPOJO supports other metadata annotation approaches
15
The Basics
16
• Assume we have the following service interface
The Basics
public interface Printer {
void print(String s);
}
17
• Assume we have the following service interface
• Here is an iPOJO component providing the service
The Basics
public interface Printer {
void print(String s);
}
@Component
@Provides
public class PrinterImpl implements Printer {
public void print(String s) {
// Print the string somehow...
}
}
18
The Basics
• Assume we define a text editor like this
public interface TextEditor {
public void print();
public String getText();
public void setText(String s);
public int getSelectionStart();
public int getSelectionEnd();
}
19
The Basics
• Assume we define a text editor like this
• Text editor implementation with service dependency
@Component
public class TextEditorImpl implements TextEditor {
@Requires
private Printer m_printer;
public void print() {
m_printer.print(getText());
}
...
}
public interface TextEditor {
public void print();
public String getText();
public void setText(String s);
public int getSelectionStart();
public int getSelectionEnd();
}
20
Providing Services
21
Providing Services
• Service providers can define dynamic service
properties to reflect run-time state changes
22
Providing Services
• Service providers can define dynamic service
properties to reflect run-time state changes
• e.g., indicate printer status
@Component
@Provides
public class PrinterImpl implements Printer {
@ServiceProperty(value=true)‫‏‬
private boolean ready;
public void deviceCallback(boolean status) {
ready = status;
}
public void print(String s) {
if (ready) {
// print the string
}
}
}
23
Providing Services
• Service providers can define dynamic service
properties to reflect run-time state changes
• e.g., indicate printer status
@Component
@Provides
public class PrinterImpl implements Printer {
@ServiceProperty(value=true)‫‏‬
private boolean ready;
public void deviceCallback(boolean status) {
ready = status;
}
public void print(String s) {
if (ready) {
// print the string
}
}
}
Changes to the associated variable are
automatically reflected in the registered service's
properties at run time.
24
Providing Services
• Service providers can define dynamic service
properties to reflect run-time state changes
• e.g., indicate printer status
@Component
@Provides
public class PrinterImpl implements Printer {
@ServiceProperty(value=true)‫‏‬
private boolean ready;
public void deviceCallback(boolean status) {
ready = status;
}
public void print(String s) {
if (ready) {
// print the string
}
}
}
Client code can filter on this:
@Component
public class TextEditorImpl implements TextEditor {
@Requires(filter=”(ready=true)”)
private Printer m_printer;
...
}
25
Providing Services
• Service providers can participate in service life cycle
• Necessary to indicate unsatisfied requirements that cannot
be managed by container
26
Providing Services
• Service providers can participate in service life cycle
• Necessary to indicate unsatisfied requirements that cannot
be managed by container
• e.g., broken Bluetooth connection
@Component
@Provides
public class PrinterImpl implements Printer {
@Controller
private boolean m_valid = true;
...
public void connectionCallback(boolean status)
{
m_valid = status;
}
...
}
27
Providing Services
• Service providers can participate in service life cycle
• Necessary to indicate unsatisfied requirements that cannot
be managed by container
• e.g., broken Bluetooth connection
@Component
@Provides
public class PrinterImpl implements Printer {
@Controller
private boolean m_valid = true;
...
public void connectionCallback(boolean status)
{
m_valid = status;
}
...
}
The component programmatically controls whether
its service is valid, in addition to any other service
dependencies already managed by the container.
28
Using Services
29
Using Services
• Let's make our text editor extensible with plugins,
something like
Text editor
Plugins
Printer
30
Using Services
• Let's make our text editor extensible with plugins,
something like
• We define a simple plugin interface, like
• What about our text editor implementation?
Text editor
Plugins
Printer
public interface Plugin {
public String getName();
public void execute(TextEditor te);
}
31
Using Services
• We add a dependency to our text editor for plugins
@Component
public class TextEditorImpl implements TextEditor
{
@Requires
private Printer m_printer;
@Requires‫‏‬
private Plugin[] m_plugins;
public void print() {
m_printer.print(getText());
}
public void listPlugins() {
for (int i = 0; i < m_plugins.length; i++) {
System.out.println(m_plugins[i].getName();
}
}
...
}
32
Using Services
• We add a dependency to our text editor for plugins
@Component
public class TextEditorImpl implements TextEditor
{
@Requires(optional=true)
private Printer m_printer;
@Requires(optional=true)‫‏‬
private Plugin[] m_plugins;
public void print() {
m_printer.print(getText());
}
public void listPlugins() {
for (int i = 0; i < m_plugins.length; i++) {
System.out.println(m_plugins[i].getName();
}
}
...
}
Although cardinality is assumed depending on
the field type, we probably also want to specify
that the printer and plugins are optional.
33
Using Services
• We add a dependency to our text editor for plugins
@Component
public class TextEditorImpl implements TextEditor
{
@Requires(optional=true)
private Printer m_printer;
@Requires(optional=true)‫‏‬
private Plugin[] m_plugins;
public void print() {
m_printer.print(getText());
}
public void listPlugins() {
for (int i = 0; i < m_plugins.length; i++) {
System.out.println(m_plugins[i].getName();
}
}
...
}
By default, the container uses the Null Object
pattern, so components do not need to check for
null on optional services.
34
Using Services
• We add a dependency to our text editor for plugins
@Component
public class TextEditorImpl implements TextEditor
{
@Requires(optional=true,nullable=false)
private Printer m_printer;
@Requires(optional=true)‫‏‬
private Plugin[] m_plugins;
public void print() {
m_printer.print(getText());
}
public void listPlugins() {
for (int i = 0; i < m_plugins.length; i++) {
System.out.println(m_plugins[i].getName();
}
}
...
}
However, it is also possible to actually get a null.
35
Using Services
• We add a dependency to our text editor for plugins
@Component
public class TextEditorImpl implements TextEditor
{
@Requires(optional=true,nullable=false)
private Printer m_printer;
@Requires(optional=true)‫‏‬
private Plugin[] m_plugins;
public void print() {
if (m_printer != null) {
m_printer.print(getText());
}
}
public void listPlugins() {
for (int i = 0; i < m_plugins.length; i++) {
System.out.println(m_plugins[i].getName();
}
}
...
But now we will have to check for null...
36
Using Services
• We add a dependency to our text editor for plugins
@Component
public class TextEditorImpl implements TextEditor
{
@Requires(optional=true,nullable=false)
private Printer m_printer;
@Requires(optional=true)‫‏‬
private Plugin[] m_plugins;
public void print() {
if (m_printer != null) {
m_printer.print(getText());
}
}
public void listPlugins() {
for (int i = 0; i < m_plugins.length; i++) {
System.out.println(m_plugins[i].getName();
}
}
...
This raises some concurrency issues, but keep
those in mind for later...
37
Using Services
• We add a dependency to our text editor for plugins
@Component
public class TextEditorImpl implements TextEditor {
@Requires(optional=true, 
default-implementation=FilePrinter.class)
private Printer m_printer;
@Requires(optional=true)‫‏‬
private Plugin[] m_plugins;
public void print() {
m_printer.print(getText());
}
public void listPlugins() {
for (int i = 0; i < m_plugins.length; i++) {
System.out.println(m_plugins[i].getName();
}
}
...
}
Instead, we could specify a default implementation.
38
Using Services
• Service dependencies have a binding policy
• Static – snapshot, any change impacts life cycle
• Dynamic – default, tracks run-time changes
• Dynamic priority – tracks priority run-time changes
39
Using Services
• Service dependencies have a binding policy
• Static – snapshot, any change impacts life cycle
• Dynamic – default, tracks run-time changes
• Dynamic priority – tracks priority run-time changes
@Component
public class TextEditorImpl implements TextEditor {
@Requires(optional=true,policy=”dynamic-priority”)
private Printer m_printer;
@Requires(optional=true)‫‏‬
private Plugin[] m_plugins;
public void print() {
m_printer.print(getText());
}
...
}
40
Using Services
• Service dependencies have a binding policy
• Static – snapshot, any change impacts life cycle
• Dynamic – default, tracks run-time changes
• Dynamic priority – tracks priority run-time changes
@Component
public class TextEditorImpl implements TextEditor {
@Requires(optional=true,policy=”dynamic-priority”)
private Printer m_printer;
@Requires(optional=true)‫‏‬
private Plugin[] m_plugins;
public void print() {
m_printer.print(getText());
}
...
}
OSGi service ranking is default priority...
41
Using Services
• Service dependencies have a binding policy
• Static – snapshot, any change impacts life cycle
• Dynamic – default, tracks run-time changes
• Dynamic priority – tracks priority run-time changes
@Component
public class TextEditorImpl implements TextEditor {
@Requires(optional=true,policy=”dynamic-priority”, 
comparator=NearestPrinter.class)‫‏‬
private Printer m_printer;
@Requires(optional=true)‫‏‬
private Plugin[] m_plugins;
public void print() {
m_printer.print(getText());
}
...
}
But a custom sort order can be specified.
42
Using Services
• Temporal dependencies associate service usage
with method-level access
• For a dependency that is only required at a given time
• e.g., services that are only used at initialization
43
Using Services
• Temporal dependencies associate service usage
with method-level access
• For a dependency that is only required at a given time
• e.g., services that are only used at initialization
@Component
public class TextEditorImpl implements TextEditor {
@Temporal
private Printer m_printer;
@Requires(optional=true)‫‏‬
private Plugin[] m_plugins;
public void print() {
m_printer.print(getText());
}
...
}
44
Using Services
• Temporal dependencies associate service usage
with method-level access
• For a dependency that is only required at a given time
• e.g., services that are only used at initialization
@Component
public class TextEditorImpl implements TextEditor {
@Temporal‫‏‬
private Printer m_printer;
@Requires(optional=true)‫‏‬
private Plugin[] m_plugins;
public void print() {
m_printer.print(getText());
}
...
}
If the service is not available, it will wait and
eventually timeout and throw an exception. By
default, all methods accessing the service are
managed, but they can be specified.
45
Using Services
• Temporal dependencies associate service usage
with method-level access
• For a dependency that is only required at a given time
• e.g., services that are only used at initialization
@Component
public class TextEditorImpl implements TextEditor {
@Temporal(timeout=5000)‫‏‬
private Printer m_printer;
@Requires(optional=true)‫‏‬
private Plugin[] m_plugins;
public void print() {
m_printer.print(getText());
}
...
}
Can specify the timeout value or disable the
timeout altogether.
46
Using Services
• Callback methods can be associated with managed
service dependencies
@Component
public class TextEditorImpl implements TextEditor
{
...
@Requires(id=”plugins”,optional=true)‫‏‬
private Plugin[] m_plugins;
@Bind(id=”plugins”)‫‏‬
private void addPlugin() {
// Update menus
}
@Unbind(id=”plugins”)‫‏‬
private void removePlugin() {
// Update menus
}
...
}
47
Using Services
• Callback methods can be associated with managed
service dependencies
@Component
public class TextEditorImpl implements TextEditor
{
...
@Requires(id=”plugins”,optional=true)‫‏‬
private Plugin[] m_plugins;
@Bind(id=”plugins”)‫‏‬
private void addPlugin() {
// Update menus
}
@Unbind(id=”plugins”)‫‏‬
private void removePlugin() {
// Update menus
}
...
}
Binding methods will be called whenever
the managed array of plugins changes.
48
Using Services
• Callback methods can be associated with managed
service dependencies
@Component
public class TextEditorImpl implements TextEditor
{
...
@Requires(id=”plugins”,optional=true)‫‏‬
private Plugin[] m_plugins;
@Bind(id=”plugins”)‫‏‬
private void addPlugin(ServiceReference ref) {
// Update menus
}
@Unbind(id=”plugins”)‫‏‬
private void removePlugin(ServiceReference ref)
{
// Update menus
}
...
Binding methods can also receive service
reference, if necessary.
49
Using Services
• Callback methods can be associated with managed
service dependencies
@Component
public class TextEditorImpl implements TextEditor {
...
// Manage plugins ourselves
private Plugin[] m_plugins;
@Bind(id=”plugins”,aggregate=true,optional=true)‫‏‬
private synchronized void addPlugin(Plugin p) {
// Update menus
}
@Unbind(id=”plugins”)‫‏‬
private synchronized void removePlugin(Plugin p) {
// Update menus
}
...
}
Also possible to handle service
management ourselves, but this definitely
requires synchronization.
50
Using Services
• Callback methods can be associated with managed
service dependencies
@Component
public class TextEditorImpl implements TextEditor {
...
// Manage plugins ourselves
private Plugin[] m_plugins;
@Bind(id=”plugins”,aggregate=true,optional=true)‫‏‬
private synchronized void addPlugin(
Plugin p, ServiceReference ref) {
// Update menus
}
@Unbind(id=”plugins”)‫‏‬
private synchronized void removePlugin(
Plugin p, ServiceReference ref) {
// Update menus
}
...
}
Still possible to get the service
reference in this case.
51
Using Services
• Recall previous concurrency issues...
@Component
public class TextEditorImpl implements TextEditor
{
@Requires(optional=true)‫‏‬
private Printer m_printer;
@Requires(optional=true)‫‏‬
private Plugin[] m_plugins;
public void print() {
if (m_printer != null) {
m_printer.print(getText());
}
}
...
}
52
Using Services
• Recall previous concurrency issues...
@Component
public class TextEditorImpl implements TextEditor
{
@Requires(optional=true)‫‏‬
private Printer m_printer;
@Requires(optional=true)‫‏‬
private Plugin[] m_plugins;
public void print() {
if (m_printer != null) {
m_printer.print(getText());
}
}
...
}
Is this check-then-act action valid?
53
Using Services
• Recall previous concurrency issues...
@Component
public class TextEditorImpl implements TextEditor
{
@Requires(optional=true)‫‏‬
private Printer m_printer;
@Requires(optional=true)‫‏‬
private Plugin[] m_plugins;
public void print() {
if (m_printer != null) {
m_printer.print(getText());
}
}
...
}
Thread local service reference
copies are cached upon access
until the thread exits to ensure a
consistent view of services...
54
Using Services
• Recall previous concurrency issues...
@Component
public class TextEditorImpl implements TextEditor
{
@Requires(optional=true)‫‏‬
private Printer m_printer;
@Requires(optional=true)‫‏‬
private Plugin[] m_plugins;
public void print() {
if (m_printer != null) {
m_printer.print(getText());
}
}
...
}
Thread enters here.
55
Using Services
• Recall previous concurrency issues...
@Component
public class TextEditorImpl implements TextEditor
{
@Requires(optional=true)‫‏‬
private Printer m_printer;
@Requires(optional=true)‫‏‬
private Plugin[] m_plugins;
public void print() {
if (m_printer != null) {
m_printer.print(getText());
}
}
...
}
First use caches reference.
56
Using Services
• Recall previous concurrency issues...
@Component
public class TextEditorImpl implements TextEditor
{
@Requires(optional=true)‫‏‬
private Printer m_printer;
@Requires(optional=true)‫‏‬
private Plugin[] m_plugins;
public void print() {
if (m_printer != null) {
m_printer.print(getText());
}
}
...
}
Cached reference reused here.
57
Using Services
• Recall previous concurrency issues...
@Component
public class TextEditorImpl implements TextEditor
{
@Requires(optional=true)‫‏‬
private Printer m_printer;
@Requires(optional=true)‫‏‬
private Plugin[] m_plugins;
public void print() {
if (m_printer != null) {
m_printer.print(getText());
}
}
...
}
Cached reference released here.
58
Using Services
• Recall previous concurrency issues...
@Component
public class TextEditorImpl implements TextEditor
{
@Requires(optional=true)‫‏‬
private Printer m_printer;
@Requires(optional=true)‫‏‬
private Plugin[] m_plugins;
public void print() {
if (m_printer != null) {
m_printer.print(getText());
}
}
...
}
Cached service references work
for aggregate dependencies and
across invocations if thread calls
out from a method and re-enters.
59
Using Services
• Recall previous concurrency issues...
@Component
public class TextEditorImpl implements TextEditor
{
@Requires(optional=true)‫‏‬
private Printer m_printer;
@Requires(optional=true)‫‏‬
private Plugin[] m_plugins;
public void print() {
if (m_printer != null) {
m_printer.print(getText());
}
}
...
}
Components still need to guard
their own shared state to be
thread safe.
60
Using Services
• Components can receive life-cycle callbacks
• i.e., be notified when their dependencies are valid
@Component
public class TextEditorImpl implements TextEditor
{
@Requires
private Printer m_printer;
@Requires(optional=true)‫‏‬
private Plugin[] m_plugins;
@Validate
private void valid() { /* do something */ }
@Invalidate
private void invalid() { /* do something */ }
...
}
61
Configuring Instances
62
Configuring Components
• Component instances can be configured...
• ...but first, how are instances created?
63
Configuring Components
• Component instances can be configured...
• ...but first, how are instances created?
• Recall our simple printer service
@Component
@Provides
public class PrinterImpl implements Printer
{
public void print(String s) {
// print the string
}
}
64
Configuring Components
• Component instances can be configured...
• ...but first, how are instances created?
• Recall our simple printer service
@Component
@Provides
public class PrinterImpl implements Printer
{
public void print(String s) {
// print the string
}
} This actually defines a component
type, for which iPOJO automatically
registers a factory service.
65
Configuring Components
• Component instances can be configured...
• ...but first, how are instances created?
• Recall our simple printer service
@Component
@Provides
public class PrinterImpl implements Printer
{
public void print(String s) {
// print the string
}
}
metadata.xml
<ipojo>
<instance component=”org.foo.PrinterImpl”/>
</ipojo>
Instances are created by declaring
them in a metadata file...
66
Configuring Components
• Component instances can be configured...
• ...but first, how are instances created?
• Recall our simple printer service
@Component
@Provides
public class PrinterImpl implements Printer
{
public void print(String s) {
// print the string
}
}
metadata.xml
<ipojo>
<instance component=”org.foo.PrinterImpl”/>
</ipojo>
Need not be in the same bundle;
thus, you can deploy your types and
deploy your instances separately.
67
Configuring Components
• Created instances can be configured directly
• First, modify our service to have configuration properties
public interface Printer {
void setProperties(Dictionary config);
void print(String s);
}
@Component
@Provides
public class PrinterImpl implements Printer
{
@Property(name=”printer.config”)‫‏‬
private Dictionary m_config;
public void setProperties(Map config) {
m_config = config;
}
public void print(String s) {
// Print the string somehow...
}
}
68
Configuring Components
• Created instances can be configured directly
• First, modify our service to have configuration properties
public interface Printer {
void setProperties(Dictionary config);
void print(String s);
}
@Component
@Provides
public class PrinterImpl implements Printer
{
@Property(name=”printer.config”)‫‏‬
private Dictionary m_config;
public void setProperties(Map config) {
m_config = config;
}
public void print(String s) {
// Print the string somehow...
}
}
We've modified our interface to
accept a property dictionary,
although this is not necessary...
69
Configuring Components
• Created instances can be configured directly
• First, modify our service to have configuration properties
public interface Printer {
void setProperties(Dictionary config);
void print(String s);
}
@Component
@Provides
public class PrinterImpl implements Printer
{
@Property(name=”printer.config”)‫‏‬
private Dictionary m_config;
public void setProperties(Map config) {
m_config = config;
}
public void print(String s) {
// Print the string somehow...
}
}
And we've specified a field in our
implementation to be injected with
the configuration properties.
70
Configuring Components
• Now instances can be declared and directly
configured in the metadata file
metadata.xml
<ipojo>
<instance component=”org.foo.PrinterImpl”>
<property name=”printer.config”>
<property name=”duplex” value=”true”/>
<property name=”orientation” value=”landscape”/
>
</property>
</instance>
</ipojo>
71
Configuring Components
• Now instances can be declared and directly
configured in the metadata file
metadata.xml
<ipojo>
<instance component=”org.foo.PrinterImpl”>
<property name=”printer.config”>
<property name=”duplex” value=”true”/>
<property name=”orientation” value=”landscape”/
>
</property>
</instance>
</ipojo>
While scalar properties are
supported, this example assembles
properties into a dictionary for
injection into the associated field.
72
Configuring Components
• Managed services from Configuration Admin are
supported...
metadata.xml
<ipojo>
<instance component=”org.foo.PrinterImpl”>
<property name=”managed.service.pid” value=”foo”/>
<property name=”printer.config”>
<property name=”duplex” value=”true”/>
<property name=”orientation” value=”landscape”/
>
</property>
</instance>
</ipojo>
73
Configuring Components
• Managed services from Configuration Admin are
supported...
metadata.xml
<ipojo>
<instance component=”org.foo.PrinterImpl”>
<property name=”managed.service.pid” value=”foo”/>
<property name=”printer.config”>
<property name=”duplex” value=”true”/>
<property name=”orientation” value=”landscape”/
>
</property>
</instance>
</ipojo>
Component instance will be dynamically
injected with named configuration from
Configuration Admin.
74
Configuring Components
• Managed service factories from Configuration Admin
are also supported...
• In this case, component factory services are assigned a
managed service factory PID
• Default PID is the component class name
• Simply add configurations to Configuration Admin
associated with the appropriate factory PID
75
Configuring Components
• Managed service factories from Configuration Admin
are also supported...
• In this case, component factory services are assigned a
managed service factory PID
• Default PID is the component class name
• Simply add configurations to Configuration Admin
associated with the appropriate factory PID
For both managed services and managed
factories, configuration changes are
properly tracked and injected at run time.
76
Creating Composites
77
Creating Composites
• Now we have all the pieces in place, let's create a
text editor
78
Creating Composites
• Now we have all the pieces in place, let's create a
text editor
We create one text editor instance...
79
Creating Composites
• Now we have all the pieces in place, let's create a
text editor
We create any number of plugin instances...
80
Creating Composites
• Now we have all the pieces in place, let's create a
text editor
And we create a configured printer instance.
81
Creating Composites
• Now we have all the pieces in place, let's create a
text editor
iPOJO correctly binds them and manages
their dynamic availability at run time...
82
Creating Composites
• This configuration might look something like this...
metadata.xml
<ipojo>
<instance component=”org.bar.TextEditorImpl”/>
<instance component=”org.woz.SpellCheckPlugin”/>
<instance component=”org.foo.PrinterImpl”>
<property name=”printer.configuration”>
<property name=”duplex” value=”true”/>
<property name=”orientation” value=”landscape”/
>
</property>
</instance>
</ipojo>
83
Creating Composites
• This configuration might look something like this...
metadata.xml
<ipojo>
<instance component=”org.bar.TextEditorImpl”/>
<instance component=”org.woz.SpellCheckPlugin”/>
<instance component=”org.foo.PrinterImpl”>
<property name=”printer.configuration”>
<property name=”duplex” value=”true”/>
<property name=”orientation” value=”landscape”/
>
</property>
</instance>
</ipojo>
All resulting services are published into the
OSGi service registry...hmm...
84
Creating Composites
• This configuration might look something like this...
metadata.xml
<ipojo>
<instance component=”org.bar.TextEditorImpl”/>
<instance component=”org.woz.SpellCheckPlugin”/>
<instance component=”org.foo.PrinterImpl”>
<property name=”printer.configuration”>
<property name=”duplex” value=”true”/>
<property name=”orientation” value=”landscape”/
>
</property>
</instance>
</ipojo> Recall our configurable printer service definition:
public interface Printer {
void setProperties(Map config);
void print(String s);
}
What happens if someone else decides to
change our printer configuration?
85
Creating Composites
• This configuration might look something like this...
metadata.xml
<ipojo>
<instance component=”org.bar.TextEditorImpl”/>
<instance component=”org.woz.SpellCheckPlugin”/>
<instance component=”org.foo.PrinterImpl”>
<property name=”printer.configuration”>
<property name=”duplex” value=”true”/>
<property name=”orientation” value=”landscape”/
>
</property>
</instance>
</ipojo>
Services are global, so anyone can use them
and/or change them. Bummer!
86
Creating Composites
• We really want something like...
scope
87
Creating Composites
• iPOJO composites do just that...
metadata.xml
<ipojo>
<composite name=”ExtensibleTextEditor”>
<instance component=”org.bar.TextEditorImpl”/>
<instance component=”org.woz.SpellCheckPlugin”/>
<instance component=”org.foo.PrinterImpl”>
<property name=”printer.configuration”>
<property name=”duplex” value=”true”/>
<property name=”orientation” value=”landscape”/
>
</property>
</instance>
</composite>
</ipojo>
88
Creating Composites
• iPOJO composites do just that...
metadata.xml
<ipojo>
<composite name=”ExtensibleTextEditor”>
<instance component=”org.bar.TextEditorImpl”/>
<instance component=”org.woz.SpellCheckPlugin”/>
<instance component=”org.foo.PrinterImpl”>
<property name=”printer.configuration”>
<property name=”duplex” value=”true”/>
<property name=”orientation” value=”landscape”/
>
</property>
</instance>
</composite>
</ipojo>
Composites declare contained instances
and create a scope for them, without any
changes to the components themselves.
89
Creating Composites
• Perhaps we don't want specific implementations...
metadata.xml
<ipojo>
<composite name=”ExtensibleTextEditor”>
<instance component=”org.bar.TextEditorImpl”/>
<sub-service action=”instantiate”
specification=”org.bar.Plugin”
aggregate=”true” optional=”true”/>
<sub-service action=”instantiate”
specification=”org.foo.Printer”>
<property name=”printer.configuration”>
<property name=”duplex” value=”true”/>
<property name=”orientation” value=”landscape”/>
</property>
</sub-service>
</composite>
</ipojo>
90
Creating Composites
• Perhaps we don't want specific implementations...
metadata.xml
<ipojo>
<composite name=”ExtensibleTextEditor”>
<instance component=”org.bar.TextEditorImpl”/>
<sub-service action=”instantiate”
specification=”org.bar.Plugin”
aggregate=”true” optional=”true”/>
<sub-service action=”instantiate”
specification=”org.foo.Printer”>
<property name=”printer.configuration”>
<property name=”duplex” value=”true”/>
<property name=”orientation” value=”landscape”/>
</property>
</sub-service>
</composite>
</ipojo>
Composite sub-services specify
only the desired service interface,
leaving iPOJO to inject an available
implementation at run time.
91
Creating Composites
• Composites also support context-bound properties
• Context sources are a dictionary of run-time properties
metadata.xml
<ipojo>
<composite name=”ExtensibleTextEditor”>
<instance component=”org.bar.TextEditorImpl”/>
<sub-service action=”instantiate” specification=”org.foo.Printer”
context-source=”global:user-context-source”
filter=”(location=${user.location})”>
<property name=”printer.configuration”>
<property name=”duplex” value=”true”/>
<property name=”orientation” value=”landscape”/>
</property>
</sub-service>
<sub-service action=”instantiate”
specification=”org.bar.Plugin”
aggregate=”true” optional=”true”/>
</composite>
</ipojo>
92
Creating Composites
• Composites also support context-bound properties
• Context sources are a dictionary of run-time properties
metadata.xml
<ipojo>
<composite name=”ExtensibleTextEditor”>
<instance component=”org.bar.TextEditorImpl”/>
<sub-service action=”instantiate” specification=”org.foo.Printer”
context-source=”global:user-context-source”
filter=”(location=${user.location})”>
<property name=”printer.configuration”>
<property name=”duplex” value=”true”/>
<property name=”orientation” value=”landscape”/>
</property>
</sub-service>
<sub-service action=”instantiate”
specification=”org.bar.Plugin”
aggregate=”true” optional=”true”/>
</composite>
</ipojo>
A sub-service can specify the identifier of a
global or local context source, such as in
this example for user location context...
93
Creating Composites
• Composites also support context-bound properties
• Context sources are a dictionary of run-time properties
metadata.xml
<ipojo>
<composite name=”ExtensibleTextEditor”>
<instance component=”org.bar.TextEditorImpl”/>
<sub-service action=”instantiate” specification=”org.foo.Printer”
context-source=”global:user-context-source”
filter=”(location=${user.location})”>
<property name=”printer.configuration”>
<property name=”duplex” value=”true”/>
<property name=”orientation” value=”landscape”/>
</property>
</sub-service>
<sub-service action=”instantiate”
specification=”org.bar.Plugin”
aggregate=”true” optional=”true”/>
</composite>
</ipojo>
The sub-service filter can reference
contextual properties that will be resolved
to values at run time...
94
Creating Composites
• Composites also support context-bound properties
• Context sources are a dictionary of run-time properties
metadata.xml
<ipojo>
<composite name=”ExtensibleTextEditor”>
<instance component=”org.bar.TextEditorImpl”/>
<sub-service action=”instantiate” specification=”org.foo.Printer”
context-source=”global:user-context-source”
filter=”(location=${user.location})”>
<property name=”printer.configuration”>
<property name=”duplex” value=”true”/>
<property name=”orientation” value=”landscape”/>
</property>
</sub-service>
<sub-service action=”instantiate”
specification=”org.bar.Plugin”
aggregate=”true” optional=”true”/>
</composite>
</ipojo>
Such as in this example, where the printer
service is filtered by the current location of
the user.
95
Creating Composites
• Components can also be context sources
metadata.xml
<ipojo>
<composite name=”ExtensibleTextEditor”>
<instance component=”org.bar.TextEditorImpl”/>
<sub-service action=”instantiate” specification=”org.foo.Printer”
context-source=”global:user-context-source”
filter=”(location=${user.location})”>
<property name=”printer.configuration”>
<property name=”duplex” value=”true”/>
<property name=”orientation” value=”landscape”/>
</property>
</sub-service>
<sub-service action=”instantiate”
specification=”org.bar.Plugin”
aggregate=”true” optional=”true”
filter=”(mime.type=${mime.type})”/>
</composite>
</ipojo>
96
Creating Composites
• Components can also be context sources
metadata.xml
<ipojo>
<composite name=”ExtensibleTextEditor”>
<instance component=”org.bar.TextEditorImpl”/>
<sub-service action=”instantiate” specification=”org.foo.Printer”
context-source=”global:user-context-source”
filter=”(location=${user.location})”>
<property name=”printer.configuration”>
<property name=”duplex” value=”true”/>
<property name=”orientation” value=”landscape”/>
</property>
</sub-service>
<sub-service action=”instantiate”
specification=”org.bar.Plugin”
aggregate=”true” optional=”true”
filter=”(mime.type=${mime.type})”/>
</composite>
</ipojo>
For example, the text editor component
implements a context source that publishes
its current document MIME type...
97
Creating Composites
• Components can also be context sources
metadata.xml
<ipojo>
<composite name=”ExtensibleTextEditor”>
<instance component=”org.bar.TextEditorImpl”/>
<sub-service action=”instantiate” specification=”org.foo.Printer”
context-source=”global:user-context-source”
filter=”(location=${user.location})”>
<property name=”printer.configuration”>
<property name=”duplex” value=”true”/>
<property name=”orientation” value=”landscape”/>
</property>
</sub-service>
<sub-service action=”instantiate”
specification=”org.bar.Plugin”
aggregate=”true” optional=”true”
filter=”(mime.type=${mime.type})”/>
</composite>
</ipojo>
Thus, we can dynamically track plugins
that are relevant to the current MIME type.
98
Creating Composites
• Finally, composites are actually normal components
• i.e., they have factories and can be instantiated
metadata.xml
<ipojo>
<composite name=”ExtensibleTextEditor”>
<provides action=”implement”
specification=”org.foo.TextEditor”/>
<instance component=”org.bar.TextEditorImpl”/>
<sub-service action=”import”
specification=”org.foo.Printer”/>
<sub-service action=”instantiate”
specification=”org.bar.Plugin”
aggregate=”true” optional=”true”
filter=”(mime.type=${mime.type})”/>
</composite>
</ipojo>
99
Creating Composites
• Finally, composites are actually normal components
• i.e., they have factories and can be instantiated
metadata.xml
<ipojo>
<composite name=”ExtensibleTextEditor”>
<provides action=”implement”
specification=”org.bar.TextEditor”/>
<instance component=”org.bar.TextEditorImpl”/>
<sub-service action=”import”
specification=”org.foo.Printer”/>
<sub-service action=”instantiate”
specification=”org.bar.Plugin”
aggregate=”true” optional=”true”
filter=”(mime.type=${mime.type})”/>
</composite>
</ipojo>
They can provide services.
100
Creating Composites
• Finally, composites are actually normal components
• i.e., they have factories and can be instantiated
metadata.xml
<ipojo>
<composite name=”ExtensibleTextEditor”>
<provides action=”implement”
specification=”org.bar.TextEditor”/>
<instance component=”org.bar.TextEditorImpl”/>
<sub-service action=”import”
specification=”org.foo.Printer”/>
<sub-service action=”instantiate”
specification=”org.bar.Plugin”
aggregate=”true” optional=”true”
filter=”(mime.type=${mime.type})”/>
</composite>
</ipojo>
They can require services.
101
Creating Composites
• Finally, composites are actually normal components
• i.e., they have factories and can be instantiated
metadata.xml
<ipojo>
<composite name=”ExtensibleTextEditor”>
<provides action=”implement”
specification=”org.bar.TextEditor”/>
<instance component=”org.bar.TextEditorImpl”/>
<sub-service action=”import”
specification=”org.foo.Printer”/>
<sub-service action=”instantiate”
specification=”org.bar.Plugin”
aggregate=”true” optional=”true”
filter=”(mime.type=${mime.type})”/>
</composite>
</ipojo>
They can contain instances of
components providing services.
102
Creating Composites
• Finally, composites are actually normal components
• i.e., they have factories and can be instantiated
metadata.xml
<ipojo>
<composite name=”ExtensibleTextEditor”>
<provides action=”implement”
specification=”org.bar.TextEditor”/>
<instance component=”org.bar.TextEditorImpl”/>
<sub-service action=”import”
specification=”org.foo.Printer”/>
<sub-service action=”instantiate”
specification=”org.bar.Plugin”
aggregate=”true” optional=”true”
filter=”(mime.type=${mime.type})”/>
</composite>
</ipojo>
They can be instantiated into other
composites, creating a fully hierarchical
component model.
103
Conclusion
104
Conclusion
• The OSGi framework is a great platform for
dynamically extensible applications
• However, there is a price to pay in added complexity
• iPOJO aims to mitigate complexity
• Simplify the programming model without sacrificing the
underlying power
• Provide an advanced, fully hierarchical component model
for dynamically extensible applications
105
Questions?
106

Contenu connexe

Tendances

Jenkins Continuous Delivery
Jenkins Continuous DeliveryJenkins Continuous Delivery
Jenkins Continuous DeliveryJadson Santos
 
Towards a modularity maturity model - osgi users forum uk 16-nov2011
Towards a modularity maturity model - osgi users forum uk 16-nov2011Towards a modularity maturity model - osgi users forum uk 16-nov2011
Towards a modularity maturity model - osgi users forum uk 16-nov2011mfrancis
 
Bytecode Weaving in OSGi – Enhance Your Classes, Not Your Dependency graph! ...
Bytecode Weaving in OSGi – Enhance Your Classes, Not Your Dependency graph!  ...Bytecode Weaving in OSGi – Enhance Your Classes, Not Your Dependency graph!  ...
Bytecode Weaving in OSGi – Enhance Your Classes, Not Your Dependency graph! ...mfrancis
 
Cloud-ready Micro Java EE 8
Cloud-ready Micro Java EE 8Cloud-ready Micro Java EE 8
Cloud-ready Micro Java EE 8Payara
 
OSGi-friendly bytecode weaving – enhance your classes, not your dependency gr...
OSGi-friendly bytecode weaving – enhance your classes, not your dependency gr...OSGi-friendly bytecode weaving – enhance your classes, not your dependency gr...
OSGi-friendly bytecode weaving – enhance your classes, not your dependency gr...mfrancis
 
50 common web developer interview questions [2020 updated] [www.full stack....
50 common web developer interview questions [2020 updated]   [www.full stack....50 common web developer interview questions [2020 updated]   [www.full stack....
50 common web developer interview questions [2020 updated] [www.full stack....Alex Ershov
 
Native OSGi, Modular Software Development in a Native World - Alexander Broek...
Native OSGi, Modular Software Development in a Native World - Alexander Broek...Native OSGi, Modular Software Development in a Native World - Alexander Broek...
Native OSGi, Modular Software Development in a Native World - Alexander Broek...mfrancis
 
From XPages Hero to OSGi Guru: Taking the Scary out of Building Extension Lib...
From XPages Hero to OSGi Guru: Taking the Scary out of Building Extension Lib...From XPages Hero to OSGi Guru: Taking the Scary out of Building Extension Lib...
From XPages Hero to OSGi Guru: Taking the Scary out of Building Extension Lib...Paul Withers
 
Routing & Navigating Pages in Angular 2
Routing & Navigating Pages in Angular 2Routing & Navigating Pages in Angular 2
Routing & Navigating Pages in Angular 2Knoldus Inc.
 
Angular App Presentation
Angular App PresentationAngular App Presentation
Angular App PresentationElizabeth Long
 
Testing OSGi the "groovy" way - Lars Pfannenschmidt, Dennis Nobel
Testing OSGi the "groovy" way - Lars Pfannenschmidt, Dennis NobelTesting OSGi the "groovy" way - Lars Pfannenschmidt, Dennis Nobel
Testing OSGi the "groovy" way - Lars Pfannenschmidt, Dennis Nobelmfrancis
 
Spring Framework 4.0 - The Next Generation - Soft-Shake 2013
Spring Framework 4.0 - The Next Generation - Soft-Shake 2013Spring Framework 4.0 - The Next Generation - Soft-Shake 2013
Spring Framework 4.0 - The Next Generation - Soft-Shake 2013Sam Brannen
 

Tendances (20)

Angular vs react
Angular vs reactAngular vs react
Angular vs react
 
Jenkins Continuous Delivery
Jenkins Continuous DeliveryJenkins Continuous Delivery
Jenkins Continuous Delivery
 
Beyond OSGi Software Architecture
Beyond OSGi Software ArchitectureBeyond OSGi Software Architecture
Beyond OSGi Software Architecture
 
Towards a modularity maturity model - osgi users forum uk 16-nov2011
Towards a modularity maturity model - osgi users forum uk 16-nov2011Towards a modularity maturity model - osgi users forum uk 16-nov2011
Towards a modularity maturity model - osgi users forum uk 16-nov2011
 
Bytecode Weaving in OSGi – Enhance Your Classes, Not Your Dependency graph! ...
Bytecode Weaving in OSGi – Enhance Your Classes, Not Your Dependency graph!  ...Bytecode Weaving in OSGi – Enhance Your Classes, Not Your Dependency graph!  ...
Bytecode Weaving in OSGi – Enhance Your Classes, Not Your Dependency graph! ...
 
Cloud-ready Micro Java EE 8
Cloud-ready Micro Java EE 8Cloud-ready Micro Java EE 8
Cloud-ready Micro Java EE 8
 
OSGi-friendly bytecode weaving – enhance your classes, not your dependency gr...
OSGi-friendly bytecode weaving – enhance your classes, not your dependency gr...OSGi-friendly bytecode weaving – enhance your classes, not your dependency gr...
OSGi-friendly bytecode weaving – enhance your classes, not your dependency gr...
 
50 common web developer interview questions [2020 updated] [www.full stack....
50 common web developer interview questions [2020 updated]   [www.full stack....50 common web developer interview questions [2020 updated]   [www.full stack....
50 common web developer interview questions [2020 updated] [www.full stack....
 
Native OSGi, Modular Software Development in a Native World - Alexander Broek...
Native OSGi, Modular Software Development in a Native World - Alexander Broek...Native OSGi, Modular Software Development in a Native World - Alexander Broek...
Native OSGi, Modular Software Development in a Native World - Alexander Broek...
 
Java Concurrent
Java ConcurrentJava Concurrent
Java Concurrent
 
Vue.js Use Cases
Vue.js Use CasesVue.js Use Cases
Vue.js Use Cases
 
From XPages Hero to OSGi Guru: Taking the Scary out of Building Extension Lib...
From XPages Hero to OSGi Guru: Taking the Scary out of Building Extension Lib...From XPages Hero to OSGi Guru: Taking the Scary out of Building Extension Lib...
From XPages Hero to OSGi Guru: Taking the Scary out of Building Extension Lib...
 
Angularj2.0
Angularj2.0Angularj2.0
Angularj2.0
 
Routing & Navigating Pages in Angular 2
Routing & Navigating Pages in Angular 2Routing & Navigating Pages in Angular 2
Routing & Navigating Pages in Angular 2
 
Modules or microservices?
Modules or microservices?Modules or microservices?
Modules or microservices?
 
Angular App Presentation
Angular App PresentationAngular App Presentation
Angular App Presentation
 
Lecture 32
Lecture 32Lecture 32
Lecture 32
 
Testing OSGi the "groovy" way - Lars Pfannenschmidt, Dennis Nobel
Testing OSGi the "groovy" way - Lars Pfannenschmidt, Dennis NobelTesting OSGi the "groovy" way - Lars Pfannenschmidt, Dennis Nobel
Testing OSGi the "groovy" way - Lars Pfannenschmidt, Dennis Nobel
 
Spring Framework 4.0 - The Next Generation - Soft-Shake 2013
Spring Framework 4.0 - The Next Generation - Soft-Shake 2013Spring Framework 4.0 - The Next Generation - Soft-Shake 2013
Spring Framework 4.0 - The Next Generation - Soft-Shake 2013
 
Reactjs
ReactjsReactjs
Reactjs
 

Similaire à iPOJO - The Simple Life - Richard Hall, Visiting Assistant Professor at Tufts University

Angular2 with TypeScript
Angular2 with TypeScript Angular2 with TypeScript
Angular2 with TypeScript Rohit Bishnoi
 
OSGi Community Event 2010 - Dependencies, dependencies, dependencies
OSGi Community Event 2010 - Dependencies, dependencies, dependenciesOSGi Community Event 2010 - Dependencies, dependencies, dependencies
OSGi Community Event 2010 - Dependencies, dependencies, dependenciesmfrancis
 
Reactive Micro Services with Java seminar
Reactive Micro Services with Java seminarReactive Micro Services with Java seminar
Reactive Micro Services with Java seminarGal Marder
 
FORWARD 5 Key Highlights and Product Updates - Philadelphia Chapter
FORWARD 5 Key Highlights and Product Updates - Philadelphia ChapterFORWARD 5 Key Highlights and Product Updates - Philadelphia Chapter
FORWARD 5 Key Highlights and Product Updates - Philadelphia ChapterDiana Gray, MBA
 
The Basic Concept Of IOC
The Basic Concept Of IOCThe Basic Concept Of IOC
The Basic Concept Of IOCCarl Lu
 
Mulesoftmeetup4th july
Mulesoftmeetup4th julyMulesoftmeetup4th july
Mulesoftmeetup4th julyAnurag Dwivedi
 
Angular - Chapter 3 - Components
Angular - Chapter 3 - ComponentsAngular - Chapter 3 - Components
Angular - Chapter 3 - ComponentsWebStackAcademy
 
How to Architect and Develop Cloud Native Applications
How to Architect and Develop Cloud Native ApplicationsHow to Architect and Develop Cloud Native Applications
How to Architect and Develop Cloud Native ApplicationsSufyaan Kazi
 
MuleSoft Manchester Meetup #3 slides 31st March 2020
MuleSoft Manchester Meetup #3 slides 31st March 2020MuleSoft Manchester Meetup #3 slides 31st March 2020
MuleSoft Manchester Meetup #3 slides 31st March 2020Ieva Navickaite
 
.NET Core, ASP.NET Core Course, Session 17
.NET Core, ASP.NET Core Course, Session 17.NET Core, ASP.NET Core Course, Session 17
.NET Core, ASP.NET Core Course, Session 17aminmesbahi
 
Angular js 2
Angular js 2Angular js 2
Angular js 2Ran Wahle
 
Constructor injection and other new features for Declarative Services 1.4
Constructor injection and other new features for Declarative Services 1.4Constructor injection and other new features for Declarative Services 1.4
Constructor injection and other new features for Declarative Services 1.4bjhargrave
 
Designing and coding for cloud-native applications using Python, Harjinder Mi...
Designing and coding for cloud-native applications using Python, Harjinder Mi...Designing and coding for cloud-native applications using Python, Harjinder Mi...
Designing and coding for cloud-native applications using Python, Harjinder Mi...Pôle Systematic Paris-Region
 
An introduction to the office devpnp community initiative
An introduction to the office devpnp community initiativeAn introduction to the office devpnp community initiative
An introduction to the office devpnp community initiativeNigel Price
 
Ekon25 mORMot 2 Server-Side Notifications
Ekon25 mORMot 2 Server-Side NotificationsEkon25 mORMot 2 Server-Side Notifications
Ekon25 mORMot 2 Server-Side NotificationsArnaud Bouchez
 
Pragmatic Monolith-First, easy to decompose, clean architecture
Pragmatic Monolith-First, easy to decompose, clean architecturePragmatic Monolith-First, easy to decompose, clean architecture
Pragmatic Monolith-First, easy to decompose, clean architecturePiotr Pelczar
 

Similaire à iPOJO - The Simple Life - Richard Hall, Visiting Assistant Professor at Tufts University (20)

Angular2 with TypeScript
Angular2 with TypeScript Angular2 with TypeScript
Angular2 with TypeScript
 
OSGi Community Event 2010 - Dependencies, dependencies, dependencies
OSGi Community Event 2010 - Dependencies, dependencies, dependenciesOSGi Community Event 2010 - Dependencies, dependencies, dependencies
OSGi Community Event 2010 - Dependencies, dependencies, dependencies
 
Reactive Micro Services with Java seminar
Reactive Micro Services with Java seminarReactive Micro Services with Java seminar
Reactive Micro Services with Java seminar
 
FORWARD 5 Key Highlights and Product Updates - Philadelphia Chapter
FORWARD 5 Key Highlights and Product Updates - Philadelphia ChapterFORWARD 5 Key Highlights and Product Updates - Philadelphia Chapter
FORWARD 5 Key Highlights and Product Updates - Philadelphia Chapter
 
The Basic Concept Of IOC
The Basic Concept Of IOCThe Basic Concept Of IOC
The Basic Concept Of IOC
 
Angular 9
Angular 9 Angular 9
Angular 9
 
Mulesoftmeetup4th july
Mulesoftmeetup4th julyMulesoftmeetup4th july
Mulesoftmeetup4th july
 
Angular - Chapter 3 - Components
Angular - Chapter 3 - ComponentsAngular - Chapter 3 - Components
Angular - Chapter 3 - Components
 
How to Architect and Develop Cloud Native Applications
How to Architect and Develop Cloud Native ApplicationsHow to Architect and Develop Cloud Native Applications
How to Architect and Develop Cloud Native Applications
 
MuleSoft Manchester Meetup #3 slides 31st March 2020
MuleSoft Manchester Meetup #3 slides 31st March 2020MuleSoft Manchester Meetup #3 slides 31st March 2020
MuleSoft Manchester Meetup #3 slides 31st March 2020
 
Embedded Android : System Development - Part IV (Android System Services)
Embedded Android : System Development - Part IV (Android System Services)Embedded Android : System Development - Part IV (Android System Services)
Embedded Android : System Development - Part IV (Android System Services)
 
.NET Core, ASP.NET Core Course, Session 17
.NET Core, ASP.NET Core Course, Session 17.NET Core, ASP.NET Core Course, Session 17
.NET Core, ASP.NET Core Course, Session 17
 
Angular js 2
Angular js 2Angular js 2
Angular js 2
 
Angular IO
Angular IOAngular IO
Angular IO
 
Constructor injection and other new features for Declarative Services 1.4
Constructor injection and other new features for Declarative Services 1.4Constructor injection and other new features for Declarative Services 1.4
Constructor injection and other new features for Declarative Services 1.4
 
Spring
SpringSpring
Spring
 
Designing and coding for cloud-native applications using Python, Harjinder Mi...
Designing and coding for cloud-native applications using Python, Harjinder Mi...Designing and coding for cloud-native applications using Python, Harjinder Mi...
Designing and coding for cloud-native applications using Python, Harjinder Mi...
 
An introduction to the office devpnp community initiative
An introduction to the office devpnp community initiativeAn introduction to the office devpnp community initiative
An introduction to the office devpnp community initiative
 
Ekon25 mORMot 2 Server-Side Notifications
Ekon25 mORMot 2 Server-Side NotificationsEkon25 mORMot 2 Server-Side Notifications
Ekon25 mORMot 2 Server-Side Notifications
 
Pragmatic Monolith-First, easy to decompose, clean architecture
Pragmatic Monolith-First, easy to decompose, clean architecturePragmatic Monolith-First, easy to decompose, clean architecture
Pragmatic Monolith-First, easy to decompose, clean architecture
 

Plus de 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 Lyaruumfrancis
 
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
 

Plus de 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)
 

Dernier

Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Nikki Chapple
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Kaya Weers
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...itnewsafrica
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...itnewsafrica
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical InfrastructureVarsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructureitnewsafrica
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxGenerative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxfnnc6jmgwh
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfpanagenda
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024TopCSSGallery
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Strongerpanagenda
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 

Dernier (20)

Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical InfrastructureVarsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxGenerative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 

iPOJO - The Simple Life - Richard Hall, Visiting Assistant Professor at Tufts University

  • 1. June 10-11, 2008 Berlin, Germany iPOJO: The Simple Life Richard S. Hall
  • 2. 2 Agenda • Introduction & Background • iPOJO Overview • The Basics • Providing Services • Using Services • Configuring Instances • Creating Composites • Conclusion
  • 4. 4 Introduction • OSGi technology provides an interesting platform for creating dynamically extensible applications • However, dealing with dynamism is a pain... • ...raising the abstraction is necessary • Developers should concentrate on application logic, not low-level OSGi mechanisms • Solving these issues is necessary if we want to move into innovative areas • Context awareness, pervasive computing, autonomic computing, etc.
  • 5. 5 Background • I started implementing the OSGi specification so that I could investigate dynamic assembly of applications • The framework was called Oscar • Unfortunately, I have not stopped implementing it 2000
  • 6. 6 Background • Humberto Cervantes and I started to discuss OSGi component models • Humberto finished a prototype of Beanome in 2002 • Defined a simple OSGi-based component model with factories and simple service dependency management 2001
  • 7. 7 Background • Humberto and I started working on a general approach to simplify OSGi dynamic service dependency management • Humberto developed Service Binder as part of his PhD • Included all of the standard mechanisms (e.g., optionality, aggregation, binding policies, etc.) 2002
  • 8. 8 Background • Declarative Services was being defined, incorporating ideas from Service Binder • Experimental versions of Service Binder introduced a composite service model • However, it proved insufficient 2004
  • 9. 9 Background • I started thinking about an improved way to create composite services using byte code generation • Peter Kriens starts thinking about using byte code manipulation to further simplify (de-cruft) dynamic dependency management • Peter gets into the details and presents a prototype in October 2005 2005
  • 10. 10 Background • Around 2006, Clement Escoffier and I started working together to create iPOJO • Combine Peter's “de-crufting” effort with the ability to create dynamic composite services • Clement does all of the hard work, I just complain about it • Which leads us to now... 2006
  • 12. 12 iPOJO Overview • Approach • Make things simple • Simple things should be simple • Not so simple things should still be reasonably simple • Complicated things should be possible • Follow POJO philosophy • Use plain old Java objects • Avoid tying application logic to component framework • Employ byte code manipulation techniques • Intercept access to component member fields • Monitor component method entry, exit, and exceptions • Be as lazy as possible
  • 13. 13 iPOJO Overview • Usage • Part of the build process, specifically packaging • First, compile component source • Then, package component as bundle (perhaps using BND) • Finally, process bundle with iPOJO manipulator • Supports Maven, Ant, and Eclipse • Example Ant task definition: <target name=”post-package” depends=”package”> <ipojo input="${output.dir}/${project.name}.jar" metadata="metadata.xml"/> </target>
  • 14. 14 iPOJO Overview • Issues • POJO-ness • iPOJO does not support constructor injection • Possible, but it is anathema to dynamism • iPOJO requires an empty constructor or a constructor with bundle context argument • Service dependencies are usable in the constructor • Possible to have constructor with other arguments, but iPOJO will not use it • iPOJO supports annotations • The examples in this presentation use annotations • However, annotations are still a form of API and reduce POJO-ness • iPOJO supports other metadata annotation approaches
  • 16. 16 • Assume we have the following service interface The Basics public interface Printer { void print(String s); }
  • 17. 17 • Assume we have the following service interface • Here is an iPOJO component providing the service The Basics public interface Printer { void print(String s); } @Component @Provides public class PrinterImpl implements Printer { public void print(String s) { // Print the string somehow... } }
  • 18. 18 The Basics • Assume we define a text editor like this public interface TextEditor { public void print(); public String getText(); public void setText(String s); public int getSelectionStart(); public int getSelectionEnd(); }
  • 19. 19 The Basics • Assume we define a text editor like this • Text editor implementation with service dependency @Component public class TextEditorImpl implements TextEditor { @Requires private Printer m_printer; public void print() { m_printer.print(getText()); } ... } public interface TextEditor { public void print(); public String getText(); public void setText(String s); public int getSelectionStart(); public int getSelectionEnd(); }
  • 21. 21 Providing Services • Service providers can define dynamic service properties to reflect run-time state changes
  • 22. 22 Providing Services • Service providers can define dynamic service properties to reflect run-time state changes • e.g., indicate printer status @Component @Provides public class PrinterImpl implements Printer { @ServiceProperty(value=true)‫‏‬ private boolean ready; public void deviceCallback(boolean status) { ready = status; } public void print(String s) { if (ready) { // print the string } } }
  • 23. 23 Providing Services • Service providers can define dynamic service properties to reflect run-time state changes • e.g., indicate printer status @Component @Provides public class PrinterImpl implements Printer { @ServiceProperty(value=true)‫‏‬ private boolean ready; public void deviceCallback(boolean status) { ready = status; } public void print(String s) { if (ready) { // print the string } } } Changes to the associated variable are automatically reflected in the registered service's properties at run time.
  • 24. 24 Providing Services • Service providers can define dynamic service properties to reflect run-time state changes • e.g., indicate printer status @Component @Provides public class PrinterImpl implements Printer { @ServiceProperty(value=true)‫‏‬ private boolean ready; public void deviceCallback(boolean status) { ready = status; } public void print(String s) { if (ready) { // print the string } } } Client code can filter on this: @Component public class TextEditorImpl implements TextEditor { @Requires(filter=”(ready=true)”) private Printer m_printer; ... }
  • 25. 25 Providing Services • Service providers can participate in service life cycle • Necessary to indicate unsatisfied requirements that cannot be managed by container
  • 26. 26 Providing Services • Service providers can participate in service life cycle • Necessary to indicate unsatisfied requirements that cannot be managed by container • e.g., broken Bluetooth connection @Component @Provides public class PrinterImpl implements Printer { @Controller private boolean m_valid = true; ... public void connectionCallback(boolean status) { m_valid = status; } ... }
  • 27. 27 Providing Services • Service providers can participate in service life cycle • Necessary to indicate unsatisfied requirements that cannot be managed by container • e.g., broken Bluetooth connection @Component @Provides public class PrinterImpl implements Printer { @Controller private boolean m_valid = true; ... public void connectionCallback(boolean status) { m_valid = status; } ... } The component programmatically controls whether its service is valid, in addition to any other service dependencies already managed by the container.
  • 29. 29 Using Services • Let's make our text editor extensible with plugins, something like Text editor Plugins Printer
  • 30. 30 Using Services • Let's make our text editor extensible with plugins, something like • We define a simple plugin interface, like • What about our text editor implementation? Text editor Plugins Printer public interface Plugin { public String getName(); public void execute(TextEditor te); }
  • 31. 31 Using Services • We add a dependency to our text editor for plugins @Component public class TextEditorImpl implements TextEditor { @Requires private Printer m_printer; @Requires‫‏‬ private Plugin[] m_plugins; public void print() { m_printer.print(getText()); } public void listPlugins() { for (int i = 0; i < m_plugins.length; i++) { System.out.println(m_plugins[i].getName(); } } ... }
  • 32. 32 Using Services • We add a dependency to our text editor for plugins @Component public class TextEditorImpl implements TextEditor { @Requires(optional=true) private Printer m_printer; @Requires(optional=true)‫‏‬ private Plugin[] m_plugins; public void print() { m_printer.print(getText()); } public void listPlugins() { for (int i = 0; i < m_plugins.length; i++) { System.out.println(m_plugins[i].getName(); } } ... } Although cardinality is assumed depending on the field type, we probably also want to specify that the printer and plugins are optional.
  • 33. 33 Using Services • We add a dependency to our text editor for plugins @Component public class TextEditorImpl implements TextEditor { @Requires(optional=true) private Printer m_printer; @Requires(optional=true)‫‏‬ private Plugin[] m_plugins; public void print() { m_printer.print(getText()); } public void listPlugins() { for (int i = 0; i < m_plugins.length; i++) { System.out.println(m_plugins[i].getName(); } } ... } By default, the container uses the Null Object pattern, so components do not need to check for null on optional services.
  • 34. 34 Using Services • We add a dependency to our text editor for plugins @Component public class TextEditorImpl implements TextEditor { @Requires(optional=true,nullable=false) private Printer m_printer; @Requires(optional=true)‫‏‬ private Plugin[] m_plugins; public void print() { m_printer.print(getText()); } public void listPlugins() { for (int i = 0; i < m_plugins.length; i++) { System.out.println(m_plugins[i].getName(); } } ... } However, it is also possible to actually get a null.
  • 35. 35 Using Services • We add a dependency to our text editor for plugins @Component public class TextEditorImpl implements TextEditor { @Requires(optional=true,nullable=false) private Printer m_printer; @Requires(optional=true)‫‏‬ private Plugin[] m_plugins; public void print() { if (m_printer != null) { m_printer.print(getText()); } } public void listPlugins() { for (int i = 0; i < m_plugins.length; i++) { System.out.println(m_plugins[i].getName(); } } ... But now we will have to check for null...
  • 36. 36 Using Services • We add a dependency to our text editor for plugins @Component public class TextEditorImpl implements TextEditor { @Requires(optional=true,nullable=false) private Printer m_printer; @Requires(optional=true)‫‏‬ private Plugin[] m_plugins; public void print() { if (m_printer != null) { m_printer.print(getText()); } } public void listPlugins() { for (int i = 0; i < m_plugins.length; i++) { System.out.println(m_plugins[i].getName(); } } ... This raises some concurrency issues, but keep those in mind for later...
  • 37. 37 Using Services • We add a dependency to our text editor for plugins @Component public class TextEditorImpl implements TextEditor { @Requires(optional=true, default-implementation=FilePrinter.class) private Printer m_printer; @Requires(optional=true)‫‏‬ private Plugin[] m_plugins; public void print() { m_printer.print(getText()); } public void listPlugins() { for (int i = 0; i < m_plugins.length; i++) { System.out.println(m_plugins[i].getName(); } } ... } Instead, we could specify a default implementation.
  • 38. 38 Using Services • Service dependencies have a binding policy • Static – snapshot, any change impacts life cycle • Dynamic – default, tracks run-time changes • Dynamic priority – tracks priority run-time changes
  • 39. 39 Using Services • Service dependencies have a binding policy • Static – snapshot, any change impacts life cycle • Dynamic – default, tracks run-time changes • Dynamic priority – tracks priority run-time changes @Component public class TextEditorImpl implements TextEditor { @Requires(optional=true,policy=”dynamic-priority”) private Printer m_printer; @Requires(optional=true)‫‏‬ private Plugin[] m_plugins; public void print() { m_printer.print(getText()); } ... }
  • 40. 40 Using Services • Service dependencies have a binding policy • Static – snapshot, any change impacts life cycle • Dynamic – default, tracks run-time changes • Dynamic priority – tracks priority run-time changes @Component public class TextEditorImpl implements TextEditor { @Requires(optional=true,policy=”dynamic-priority”) private Printer m_printer; @Requires(optional=true)‫‏‬ private Plugin[] m_plugins; public void print() { m_printer.print(getText()); } ... } OSGi service ranking is default priority...
  • 41. 41 Using Services • Service dependencies have a binding policy • Static – snapshot, any change impacts life cycle • Dynamic – default, tracks run-time changes • Dynamic priority – tracks priority run-time changes @Component public class TextEditorImpl implements TextEditor { @Requires(optional=true,policy=”dynamic-priority”, comparator=NearestPrinter.class)‫‏‬ private Printer m_printer; @Requires(optional=true)‫‏‬ private Plugin[] m_plugins; public void print() { m_printer.print(getText()); } ... } But a custom sort order can be specified.
  • 42. 42 Using Services • Temporal dependencies associate service usage with method-level access • For a dependency that is only required at a given time • e.g., services that are only used at initialization
  • 43. 43 Using Services • Temporal dependencies associate service usage with method-level access • For a dependency that is only required at a given time • e.g., services that are only used at initialization @Component public class TextEditorImpl implements TextEditor { @Temporal private Printer m_printer; @Requires(optional=true)‫‏‬ private Plugin[] m_plugins; public void print() { m_printer.print(getText()); } ... }
  • 44. 44 Using Services • Temporal dependencies associate service usage with method-level access • For a dependency that is only required at a given time • e.g., services that are only used at initialization @Component public class TextEditorImpl implements TextEditor { @Temporal‫‏‬ private Printer m_printer; @Requires(optional=true)‫‏‬ private Plugin[] m_plugins; public void print() { m_printer.print(getText()); } ... } If the service is not available, it will wait and eventually timeout and throw an exception. By default, all methods accessing the service are managed, but they can be specified.
  • 45. 45 Using Services • Temporal dependencies associate service usage with method-level access • For a dependency that is only required at a given time • e.g., services that are only used at initialization @Component public class TextEditorImpl implements TextEditor { @Temporal(timeout=5000)‫‏‬ private Printer m_printer; @Requires(optional=true)‫‏‬ private Plugin[] m_plugins; public void print() { m_printer.print(getText()); } ... } Can specify the timeout value or disable the timeout altogether.
  • 46. 46 Using Services • Callback methods can be associated with managed service dependencies @Component public class TextEditorImpl implements TextEditor { ... @Requires(id=”plugins”,optional=true)‫‏‬ private Plugin[] m_plugins; @Bind(id=”plugins”)‫‏‬ private void addPlugin() { // Update menus } @Unbind(id=”plugins”)‫‏‬ private void removePlugin() { // Update menus } ... }
  • 47. 47 Using Services • Callback methods can be associated with managed service dependencies @Component public class TextEditorImpl implements TextEditor { ... @Requires(id=”plugins”,optional=true)‫‏‬ private Plugin[] m_plugins; @Bind(id=”plugins”)‫‏‬ private void addPlugin() { // Update menus } @Unbind(id=”plugins”)‫‏‬ private void removePlugin() { // Update menus } ... } Binding methods will be called whenever the managed array of plugins changes.
  • 48. 48 Using Services • Callback methods can be associated with managed service dependencies @Component public class TextEditorImpl implements TextEditor { ... @Requires(id=”plugins”,optional=true)‫‏‬ private Plugin[] m_plugins; @Bind(id=”plugins”)‫‏‬ private void addPlugin(ServiceReference ref) { // Update menus } @Unbind(id=”plugins”)‫‏‬ private void removePlugin(ServiceReference ref) { // Update menus } ... Binding methods can also receive service reference, if necessary.
  • 49. 49 Using Services • Callback methods can be associated with managed service dependencies @Component public class TextEditorImpl implements TextEditor { ... // Manage plugins ourselves private Plugin[] m_plugins; @Bind(id=”plugins”,aggregate=true,optional=true)‫‏‬ private synchronized void addPlugin(Plugin p) { // Update menus } @Unbind(id=”plugins”)‫‏‬ private synchronized void removePlugin(Plugin p) { // Update menus } ... } Also possible to handle service management ourselves, but this definitely requires synchronization.
  • 50. 50 Using Services • Callback methods can be associated with managed service dependencies @Component public class TextEditorImpl implements TextEditor { ... // Manage plugins ourselves private Plugin[] m_plugins; @Bind(id=”plugins”,aggregate=true,optional=true)‫‏‬ private synchronized void addPlugin( Plugin p, ServiceReference ref) { // Update menus } @Unbind(id=”plugins”)‫‏‬ private synchronized void removePlugin( Plugin p, ServiceReference ref) { // Update menus } ... } Still possible to get the service reference in this case.
  • 51. 51 Using Services • Recall previous concurrency issues... @Component public class TextEditorImpl implements TextEditor { @Requires(optional=true)‫‏‬ private Printer m_printer; @Requires(optional=true)‫‏‬ private Plugin[] m_plugins; public void print() { if (m_printer != null) { m_printer.print(getText()); } } ... }
  • 52. 52 Using Services • Recall previous concurrency issues... @Component public class TextEditorImpl implements TextEditor { @Requires(optional=true)‫‏‬ private Printer m_printer; @Requires(optional=true)‫‏‬ private Plugin[] m_plugins; public void print() { if (m_printer != null) { m_printer.print(getText()); } } ... } Is this check-then-act action valid?
  • 53. 53 Using Services • Recall previous concurrency issues... @Component public class TextEditorImpl implements TextEditor { @Requires(optional=true)‫‏‬ private Printer m_printer; @Requires(optional=true)‫‏‬ private Plugin[] m_plugins; public void print() { if (m_printer != null) { m_printer.print(getText()); } } ... } Thread local service reference copies are cached upon access until the thread exits to ensure a consistent view of services...
  • 54. 54 Using Services • Recall previous concurrency issues... @Component public class TextEditorImpl implements TextEditor { @Requires(optional=true)‫‏‬ private Printer m_printer; @Requires(optional=true)‫‏‬ private Plugin[] m_plugins; public void print() { if (m_printer != null) { m_printer.print(getText()); } } ... } Thread enters here.
  • 55. 55 Using Services • Recall previous concurrency issues... @Component public class TextEditorImpl implements TextEditor { @Requires(optional=true)‫‏‬ private Printer m_printer; @Requires(optional=true)‫‏‬ private Plugin[] m_plugins; public void print() { if (m_printer != null) { m_printer.print(getText()); } } ... } First use caches reference.
  • 56. 56 Using Services • Recall previous concurrency issues... @Component public class TextEditorImpl implements TextEditor { @Requires(optional=true)‫‏‬ private Printer m_printer; @Requires(optional=true)‫‏‬ private Plugin[] m_plugins; public void print() { if (m_printer != null) { m_printer.print(getText()); } } ... } Cached reference reused here.
  • 57. 57 Using Services • Recall previous concurrency issues... @Component public class TextEditorImpl implements TextEditor { @Requires(optional=true)‫‏‬ private Printer m_printer; @Requires(optional=true)‫‏‬ private Plugin[] m_plugins; public void print() { if (m_printer != null) { m_printer.print(getText()); } } ... } Cached reference released here.
  • 58. 58 Using Services • Recall previous concurrency issues... @Component public class TextEditorImpl implements TextEditor { @Requires(optional=true)‫‏‬ private Printer m_printer; @Requires(optional=true)‫‏‬ private Plugin[] m_plugins; public void print() { if (m_printer != null) { m_printer.print(getText()); } } ... } Cached service references work for aggregate dependencies and across invocations if thread calls out from a method and re-enters.
  • 59. 59 Using Services • Recall previous concurrency issues... @Component public class TextEditorImpl implements TextEditor { @Requires(optional=true)‫‏‬ private Printer m_printer; @Requires(optional=true)‫‏‬ private Plugin[] m_plugins; public void print() { if (m_printer != null) { m_printer.print(getText()); } } ... } Components still need to guard their own shared state to be thread safe.
  • 60. 60 Using Services • Components can receive life-cycle callbacks • i.e., be notified when their dependencies are valid @Component public class TextEditorImpl implements TextEditor { @Requires private Printer m_printer; @Requires(optional=true)‫‏‬ private Plugin[] m_plugins; @Validate private void valid() { /* do something */ } @Invalidate private void invalid() { /* do something */ } ... }
  • 62. 62 Configuring Components • Component instances can be configured... • ...but first, how are instances created?
  • 63. 63 Configuring Components • Component instances can be configured... • ...but first, how are instances created? • Recall our simple printer service @Component @Provides public class PrinterImpl implements Printer { public void print(String s) { // print the string } }
  • 64. 64 Configuring Components • Component instances can be configured... • ...but first, how are instances created? • Recall our simple printer service @Component @Provides public class PrinterImpl implements Printer { public void print(String s) { // print the string } } This actually defines a component type, for which iPOJO automatically registers a factory service.
  • 65. 65 Configuring Components • Component instances can be configured... • ...but first, how are instances created? • Recall our simple printer service @Component @Provides public class PrinterImpl implements Printer { public void print(String s) { // print the string } } metadata.xml <ipojo> <instance component=”org.foo.PrinterImpl”/> </ipojo> Instances are created by declaring them in a metadata file...
  • 66. 66 Configuring Components • Component instances can be configured... • ...but first, how are instances created? • Recall our simple printer service @Component @Provides public class PrinterImpl implements Printer { public void print(String s) { // print the string } } metadata.xml <ipojo> <instance component=”org.foo.PrinterImpl”/> </ipojo> Need not be in the same bundle; thus, you can deploy your types and deploy your instances separately.
  • 67. 67 Configuring Components • Created instances can be configured directly • First, modify our service to have configuration properties public interface Printer { void setProperties(Dictionary config); void print(String s); } @Component @Provides public class PrinterImpl implements Printer { @Property(name=”printer.config”)‫‏‬ private Dictionary m_config; public void setProperties(Map config) { m_config = config; } public void print(String s) { // Print the string somehow... } }
  • 68. 68 Configuring Components • Created instances can be configured directly • First, modify our service to have configuration properties public interface Printer { void setProperties(Dictionary config); void print(String s); } @Component @Provides public class PrinterImpl implements Printer { @Property(name=”printer.config”)‫‏‬ private Dictionary m_config; public void setProperties(Map config) { m_config = config; } public void print(String s) { // Print the string somehow... } } We've modified our interface to accept a property dictionary, although this is not necessary...
  • 69. 69 Configuring Components • Created instances can be configured directly • First, modify our service to have configuration properties public interface Printer { void setProperties(Dictionary config); void print(String s); } @Component @Provides public class PrinterImpl implements Printer { @Property(name=”printer.config”)‫‏‬ private Dictionary m_config; public void setProperties(Map config) { m_config = config; } public void print(String s) { // Print the string somehow... } } And we've specified a field in our implementation to be injected with the configuration properties.
  • 70. 70 Configuring Components • Now instances can be declared and directly configured in the metadata file metadata.xml <ipojo> <instance component=”org.foo.PrinterImpl”> <property name=”printer.config”> <property name=”duplex” value=”true”/> <property name=”orientation” value=”landscape”/ > </property> </instance> </ipojo>
  • 71. 71 Configuring Components • Now instances can be declared and directly configured in the metadata file metadata.xml <ipojo> <instance component=”org.foo.PrinterImpl”> <property name=”printer.config”> <property name=”duplex” value=”true”/> <property name=”orientation” value=”landscape”/ > </property> </instance> </ipojo> While scalar properties are supported, this example assembles properties into a dictionary for injection into the associated field.
  • 72. 72 Configuring Components • Managed services from Configuration Admin are supported... metadata.xml <ipojo> <instance component=”org.foo.PrinterImpl”> <property name=”managed.service.pid” value=”foo”/> <property name=”printer.config”> <property name=”duplex” value=”true”/> <property name=”orientation” value=”landscape”/ > </property> </instance> </ipojo>
  • 73. 73 Configuring Components • Managed services from Configuration Admin are supported... metadata.xml <ipojo> <instance component=”org.foo.PrinterImpl”> <property name=”managed.service.pid” value=”foo”/> <property name=”printer.config”> <property name=”duplex” value=”true”/> <property name=”orientation” value=”landscape”/ > </property> </instance> </ipojo> Component instance will be dynamically injected with named configuration from Configuration Admin.
  • 74. 74 Configuring Components • Managed service factories from Configuration Admin are also supported... • In this case, component factory services are assigned a managed service factory PID • Default PID is the component class name • Simply add configurations to Configuration Admin associated with the appropriate factory PID
  • 75. 75 Configuring Components • Managed service factories from Configuration Admin are also supported... • In this case, component factory services are assigned a managed service factory PID • Default PID is the component class name • Simply add configurations to Configuration Admin associated with the appropriate factory PID For both managed services and managed factories, configuration changes are properly tracked and injected at run time.
  • 77. 77 Creating Composites • Now we have all the pieces in place, let's create a text editor
  • 78. 78 Creating Composites • Now we have all the pieces in place, let's create a text editor We create one text editor instance...
  • 79. 79 Creating Composites • Now we have all the pieces in place, let's create a text editor We create any number of plugin instances...
  • 80. 80 Creating Composites • Now we have all the pieces in place, let's create a text editor And we create a configured printer instance.
  • 81. 81 Creating Composites • Now we have all the pieces in place, let's create a text editor iPOJO correctly binds them and manages their dynamic availability at run time...
  • 82. 82 Creating Composites • This configuration might look something like this... metadata.xml <ipojo> <instance component=”org.bar.TextEditorImpl”/> <instance component=”org.woz.SpellCheckPlugin”/> <instance component=”org.foo.PrinterImpl”> <property name=”printer.configuration”> <property name=”duplex” value=”true”/> <property name=”orientation” value=”landscape”/ > </property> </instance> </ipojo>
  • 83. 83 Creating Composites • This configuration might look something like this... metadata.xml <ipojo> <instance component=”org.bar.TextEditorImpl”/> <instance component=”org.woz.SpellCheckPlugin”/> <instance component=”org.foo.PrinterImpl”> <property name=”printer.configuration”> <property name=”duplex” value=”true”/> <property name=”orientation” value=”landscape”/ > </property> </instance> </ipojo> All resulting services are published into the OSGi service registry...hmm...
  • 84. 84 Creating Composites • This configuration might look something like this... metadata.xml <ipojo> <instance component=”org.bar.TextEditorImpl”/> <instance component=”org.woz.SpellCheckPlugin”/> <instance component=”org.foo.PrinterImpl”> <property name=”printer.configuration”> <property name=”duplex” value=”true”/> <property name=”orientation” value=”landscape”/ > </property> </instance> </ipojo> Recall our configurable printer service definition: public interface Printer { void setProperties(Map config); void print(String s); } What happens if someone else decides to change our printer configuration?
  • 85. 85 Creating Composites • This configuration might look something like this... metadata.xml <ipojo> <instance component=”org.bar.TextEditorImpl”/> <instance component=”org.woz.SpellCheckPlugin”/> <instance component=”org.foo.PrinterImpl”> <property name=”printer.configuration”> <property name=”duplex” value=”true”/> <property name=”orientation” value=”landscape”/ > </property> </instance> </ipojo> Services are global, so anyone can use them and/or change them. Bummer!
  • 86. 86 Creating Composites • We really want something like... scope
  • 87. 87 Creating Composites • iPOJO composites do just that... metadata.xml <ipojo> <composite name=”ExtensibleTextEditor”> <instance component=”org.bar.TextEditorImpl”/> <instance component=”org.woz.SpellCheckPlugin”/> <instance component=”org.foo.PrinterImpl”> <property name=”printer.configuration”> <property name=”duplex” value=”true”/> <property name=”orientation” value=”landscape”/ > </property> </instance> </composite> </ipojo>
  • 88. 88 Creating Composites • iPOJO composites do just that... metadata.xml <ipojo> <composite name=”ExtensibleTextEditor”> <instance component=”org.bar.TextEditorImpl”/> <instance component=”org.woz.SpellCheckPlugin”/> <instance component=”org.foo.PrinterImpl”> <property name=”printer.configuration”> <property name=”duplex” value=”true”/> <property name=”orientation” value=”landscape”/ > </property> </instance> </composite> </ipojo> Composites declare contained instances and create a scope for them, without any changes to the components themselves.
  • 89. 89 Creating Composites • Perhaps we don't want specific implementations... metadata.xml <ipojo> <composite name=”ExtensibleTextEditor”> <instance component=”org.bar.TextEditorImpl”/> <sub-service action=”instantiate” specification=”org.bar.Plugin” aggregate=”true” optional=”true”/> <sub-service action=”instantiate” specification=”org.foo.Printer”> <property name=”printer.configuration”> <property name=”duplex” value=”true”/> <property name=”orientation” value=”landscape”/> </property> </sub-service> </composite> </ipojo>
  • 90. 90 Creating Composites • Perhaps we don't want specific implementations... metadata.xml <ipojo> <composite name=”ExtensibleTextEditor”> <instance component=”org.bar.TextEditorImpl”/> <sub-service action=”instantiate” specification=”org.bar.Plugin” aggregate=”true” optional=”true”/> <sub-service action=”instantiate” specification=”org.foo.Printer”> <property name=”printer.configuration”> <property name=”duplex” value=”true”/> <property name=”orientation” value=”landscape”/> </property> </sub-service> </composite> </ipojo> Composite sub-services specify only the desired service interface, leaving iPOJO to inject an available implementation at run time.
  • 91. 91 Creating Composites • Composites also support context-bound properties • Context sources are a dictionary of run-time properties metadata.xml <ipojo> <composite name=”ExtensibleTextEditor”> <instance component=”org.bar.TextEditorImpl”/> <sub-service action=”instantiate” specification=”org.foo.Printer” context-source=”global:user-context-source” filter=”(location=${user.location})”> <property name=”printer.configuration”> <property name=”duplex” value=”true”/> <property name=”orientation” value=”landscape”/> </property> </sub-service> <sub-service action=”instantiate” specification=”org.bar.Plugin” aggregate=”true” optional=”true”/> </composite> </ipojo>
  • 92. 92 Creating Composites • Composites also support context-bound properties • Context sources are a dictionary of run-time properties metadata.xml <ipojo> <composite name=”ExtensibleTextEditor”> <instance component=”org.bar.TextEditorImpl”/> <sub-service action=”instantiate” specification=”org.foo.Printer” context-source=”global:user-context-source” filter=”(location=${user.location})”> <property name=”printer.configuration”> <property name=”duplex” value=”true”/> <property name=”orientation” value=”landscape”/> </property> </sub-service> <sub-service action=”instantiate” specification=”org.bar.Plugin” aggregate=”true” optional=”true”/> </composite> </ipojo> A sub-service can specify the identifier of a global or local context source, such as in this example for user location context...
  • 93. 93 Creating Composites • Composites also support context-bound properties • Context sources are a dictionary of run-time properties metadata.xml <ipojo> <composite name=”ExtensibleTextEditor”> <instance component=”org.bar.TextEditorImpl”/> <sub-service action=”instantiate” specification=”org.foo.Printer” context-source=”global:user-context-source” filter=”(location=${user.location})”> <property name=”printer.configuration”> <property name=”duplex” value=”true”/> <property name=”orientation” value=”landscape”/> </property> </sub-service> <sub-service action=”instantiate” specification=”org.bar.Plugin” aggregate=”true” optional=”true”/> </composite> </ipojo> The sub-service filter can reference contextual properties that will be resolved to values at run time...
  • 94. 94 Creating Composites • Composites also support context-bound properties • Context sources are a dictionary of run-time properties metadata.xml <ipojo> <composite name=”ExtensibleTextEditor”> <instance component=”org.bar.TextEditorImpl”/> <sub-service action=”instantiate” specification=”org.foo.Printer” context-source=”global:user-context-source” filter=”(location=${user.location})”> <property name=”printer.configuration”> <property name=”duplex” value=”true”/> <property name=”orientation” value=”landscape”/> </property> </sub-service> <sub-service action=”instantiate” specification=”org.bar.Plugin” aggregate=”true” optional=”true”/> </composite> </ipojo> Such as in this example, where the printer service is filtered by the current location of the user.
  • 95. 95 Creating Composites • Components can also be context sources metadata.xml <ipojo> <composite name=”ExtensibleTextEditor”> <instance component=”org.bar.TextEditorImpl”/> <sub-service action=”instantiate” specification=”org.foo.Printer” context-source=”global:user-context-source” filter=”(location=${user.location})”> <property name=”printer.configuration”> <property name=”duplex” value=”true”/> <property name=”orientation” value=”landscape”/> </property> </sub-service> <sub-service action=”instantiate” specification=”org.bar.Plugin” aggregate=”true” optional=”true” filter=”(mime.type=${mime.type})”/> </composite> </ipojo>
  • 96. 96 Creating Composites • Components can also be context sources metadata.xml <ipojo> <composite name=”ExtensibleTextEditor”> <instance component=”org.bar.TextEditorImpl”/> <sub-service action=”instantiate” specification=”org.foo.Printer” context-source=”global:user-context-source” filter=”(location=${user.location})”> <property name=”printer.configuration”> <property name=”duplex” value=”true”/> <property name=”orientation” value=”landscape”/> </property> </sub-service> <sub-service action=”instantiate” specification=”org.bar.Plugin” aggregate=”true” optional=”true” filter=”(mime.type=${mime.type})”/> </composite> </ipojo> For example, the text editor component implements a context source that publishes its current document MIME type...
  • 97. 97 Creating Composites • Components can also be context sources metadata.xml <ipojo> <composite name=”ExtensibleTextEditor”> <instance component=”org.bar.TextEditorImpl”/> <sub-service action=”instantiate” specification=”org.foo.Printer” context-source=”global:user-context-source” filter=”(location=${user.location})”> <property name=”printer.configuration”> <property name=”duplex” value=”true”/> <property name=”orientation” value=”landscape”/> </property> </sub-service> <sub-service action=”instantiate” specification=”org.bar.Plugin” aggregate=”true” optional=”true” filter=”(mime.type=${mime.type})”/> </composite> </ipojo> Thus, we can dynamically track plugins that are relevant to the current MIME type.
  • 98. 98 Creating Composites • Finally, composites are actually normal components • i.e., they have factories and can be instantiated metadata.xml <ipojo> <composite name=”ExtensibleTextEditor”> <provides action=”implement” specification=”org.foo.TextEditor”/> <instance component=”org.bar.TextEditorImpl”/> <sub-service action=”import” specification=”org.foo.Printer”/> <sub-service action=”instantiate” specification=”org.bar.Plugin” aggregate=”true” optional=”true” filter=”(mime.type=${mime.type})”/> </composite> </ipojo>
  • 99. 99 Creating Composites • Finally, composites are actually normal components • i.e., they have factories and can be instantiated metadata.xml <ipojo> <composite name=”ExtensibleTextEditor”> <provides action=”implement” specification=”org.bar.TextEditor”/> <instance component=”org.bar.TextEditorImpl”/> <sub-service action=”import” specification=”org.foo.Printer”/> <sub-service action=”instantiate” specification=”org.bar.Plugin” aggregate=”true” optional=”true” filter=”(mime.type=${mime.type})”/> </composite> </ipojo> They can provide services.
  • 100. 100 Creating Composites • Finally, composites are actually normal components • i.e., they have factories and can be instantiated metadata.xml <ipojo> <composite name=”ExtensibleTextEditor”> <provides action=”implement” specification=”org.bar.TextEditor”/> <instance component=”org.bar.TextEditorImpl”/> <sub-service action=”import” specification=”org.foo.Printer”/> <sub-service action=”instantiate” specification=”org.bar.Plugin” aggregate=”true” optional=”true” filter=”(mime.type=${mime.type})”/> </composite> </ipojo> They can require services.
  • 101. 101 Creating Composites • Finally, composites are actually normal components • i.e., they have factories and can be instantiated metadata.xml <ipojo> <composite name=”ExtensibleTextEditor”> <provides action=”implement” specification=”org.bar.TextEditor”/> <instance component=”org.bar.TextEditorImpl”/> <sub-service action=”import” specification=”org.foo.Printer”/> <sub-service action=”instantiate” specification=”org.bar.Plugin” aggregate=”true” optional=”true” filter=”(mime.type=${mime.type})”/> </composite> </ipojo> They can contain instances of components providing services.
  • 102. 102 Creating Composites • Finally, composites are actually normal components • i.e., they have factories and can be instantiated metadata.xml <ipojo> <composite name=”ExtensibleTextEditor”> <provides action=”implement” specification=”org.bar.TextEditor”/> <instance component=”org.bar.TextEditorImpl”/> <sub-service action=”import” specification=”org.foo.Printer”/> <sub-service action=”instantiate” specification=”org.bar.Plugin” aggregate=”true” optional=”true” filter=”(mime.type=${mime.type})”/> </composite> </ipojo> They can be instantiated into other composites, creating a fully hierarchical component model.
  • 104. 104 Conclusion • The OSGi framework is a great platform for dynamically extensible applications • However, there is a price to pay in added complexity • iPOJO aims to mitigate complexity • Simplify the programming model without sacrificing the underlying power • Provide an advanced, fully hierarchical component model for dynamically extensible applications
  • 106. 106