Developing modular systems is not easy, in fact, you can consider modularity in a maturity grade, that starts with just data encapsulation, to extensibility, to infrastructure building. This presentation shows how the OSGi technology helps us achieve this, shows how it was used for the Oracle Event Processing product.
2. All Content and Rights Reserved (2013)
Systems using OSGi
✤ Oracle GlassFish Application Server
✤ Oracle Complex Event Processing Server
✤ IBM Websphere
✤ (Redhat) JBoss Application Server
✤ SAP NetWeaver (in progress)
✤ Apache ServiceMix
✤ Apache Camel
✤ Apache Karaf
✤ Apache Sling
Wednesday, August 28, 13
3. All Content and Rights Reserved (2013)
✤ Data encapsulation
✤ Dealing with changes
✤ Extensibility
✤ Building infrastructures
Agenda
Modularization Grade
Wednesday, August 28, 13
4. All Content and Rights Reserved (2013)
Data Encapsulation
“Information hiding achieves changeability,
comprehensibility, independent development”
- D. Parnas, 1972
Wednesday, August 28, 13
5. All Content and Rights Reserved (2013)
Data Encapsulation
✤ As brilliantly elaborated by D. Parnas in 1972
✤ The more code that is exposed, the more tests that are needed.
Wednesday, August 28, 13
6. All Content and Rights Reserved (2013)
public class Printer {
public void print(String message) {
System.out.println(message);
}
}
public class PrinterClient {
public void printMyMessage() {
new Printer().print("Hello World");
}
}
Simple example...
Wednesday, August 28, 13
7. All Content and Rights Reserved (2013)
public class Printer {
public void print(String message) {
System.out.println(message);
}
}
public class PrinterClient {
public void printMyMessage() {
new Printer().print("Hello World");
}
}
Simple example...
Modules and information hiding
Let’s share this code with other Java clients. Create a Pri
imports the Printer class and invokes it:
package manning.osgi.helloworld.client;
import manning.osgi.helloworld.Printer;
public class PrinterClient {
public void printMyMessage() {
new Printer().print("Hello World");
}
}
Figure 2.1 demonstrates this interaction.
NOTE This book attempts to be goal oriented. Rather tha
technology for the technology’s sake, the discussion of a t
print(String message)
Printer
printMyMessage()
PrinterClientprint()
Figure 2.1
class invok
the Print
Wednesday, August 28, 13
8. All Content and Rights Reserved (2013)
public class Printer {
public void print(String message) {
System.out.println(message);
}
}
public class PrinterClient {
public void printMyMessage() {
new Printer().print("Hello World");
}
}
Simple example...
Wednesday, August 28, 13
9. All Content and Rights Reserved (2013)
Objective
✤ Our goal is to minimize the number of exposed
interfaces
✤ For example, expose print() and not
printMyMessage()
Other Classesprint()
Printer
printMyMessage()
PrinterClientprint()
Other classes
Wednesday, August 28, 13
10. All Content and Rights Reserved (2013)
Modularization
package manning.osgi.helloworld;
public class Printer {
public void print(String message) {
System.out.println(message);
}
}
package manning.osgi.helloworld.client;
import manning.osgi.helloworld;
public class PrinterClient {
public void printMyMessage() {
new Printer().print("Hello World");
}
}
ld is exporting all of its public classes located in the
ld.
undle uses the manifest header Import-Package:
sgi.client
elloworld
t is importing all public classes in the package
Printer
helloworld
PrinterClient
helloworld.client
orld is exporting all of its public classes located in the
orld.
bundle uses the manifest header Import-Package:
osgi.client
helloworld
nt is importing all public classes in the package
e
d
n
-
r
d
Printer
helloworld
PrinterClient
helloworld.client
Wednesday, August 28, 13
11. All Content and Rights Reserved (2013)
Modules in OSGi
✤ A module in OSGi is called bundle
✤ A bundle is formally defined as:
✤ A JAR file
✤ OSGi-specific manifest header entries
Wednesday, August 28, 13
12. All Content and Rights Reserved (2013)
Modules in OSGi
CHAPTER 2 An OSGi framework primer
In OSGi, you accomplish this by having the provider bundle export the Java packages
that are meant to be shared, and then have the consumer bundle import the Java
packages that it needs.
To export Java packages, a bundle uses the manifest header Export-Package:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: helloworld
Export-Package: manning.osgi.helloworld
In this case, the bundle helloworld is exporting all of its public classes located in the
package manning.osgi.helloworld.
To import a Java package, a bundle uses the manifest header Import-Package:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: manning.osgi.client
Import-Package: manning.osgi.helloworld
The bundle helloworld.client is importing all public classes in the package
manning.osgi.helloworld.
As should be clear, we have
two bundles, helloworld and
helloworld.client, as shown in
figure 2.3. The bundle hello-
Printer
helloworld
PrinterClient
helloworld.client
20 CHAPTER 2 An OSGi framew
In OSGi, you accomplish this by having the pro
that are meant to be shared, and then have
packages that it needs.
To export Java packages, a bundle uses the
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: helloworld
Export-Package: manning.osgi.helloworld
In this case, the bundle helloworld is exportin
package manning.osgi.helloworld.
To import a Java package, a bundle uses the
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: manning.osgi.client
Import-Package: manning.osgi.helloworld
The bundle helloworld.client is importin
manning.osgi.helloworld.
orld is exporting all of its public classes located in the
orld.
bundle uses the manifest header Import-Package:
.osgi.client
.helloworld
nt is importing all public classes in the package
e
d
n
-
r
d
-
of
problem? That is, have we prohibited other classes
Printer
helloworld
PrinterClient
helloworld.client
Figure 2.3 The bundle helloworld includes the
Printer class. The bundle helloworld.client
includes the PrinterClient class.
the bundle helloworld is exporting all of its public classes located in the
ning.osgi.helloworld.
t a Java package, a bundle uses the manifest header Import-Package:
rsion: 1.0
festVersion: 2
olicName: manning.osgi.client
age: manning.osgi.helloworld
helloworld.client is importing all public classes in the package
i.helloworld.
d be clear, we have
s, helloworld and
client, as shown in
The bundle hello-
udes the Printer
bundle helloworld
ludes the Printer-
which makes use of
class.
solved our initial problem? That is, have we prohibited other classes
Printer
helloworld
PrinterClient
helloworld.client
Figure 2.3 The bundle helloworld includes the
Printer class. The bundle helloworld.client
includes the PrinterClient class.
Wednesday, August 28, 13
13. All Content and Rights Reserved (2013)
Modules in OSGi
CHAPTER 2 An OSGi framework primer
In OSGi, you accomplish this by having the provider bundle export the Java packages
that are meant to be shared, and then have the consumer bundle import the Java
packages that it needs.
To export Java packages, a bundle uses the manifest header Export-Package:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: helloworld
Export-Package: manning.osgi.helloworld
In this case, the bundle helloworld is exporting all of its public classes located in the
package manning.osgi.helloworld.
To import a Java package, a bundle uses the manifest header Import-Package:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: manning.osgi.client
Import-Package: manning.osgi.helloworld
The bundle helloworld.client is importing all public classes in the package
manning.osgi.helloworld.
As should be clear, we have
two bundles, helloworld and
helloworld.client, as shown in
figure 2.3. The bundle hello-
Printer
helloworld
PrinterClient
helloworld.client
20 CHAPTER 2 An OSGi framew
In OSGi, you accomplish this by having the pro
that are meant to be shared, and then have
packages that it needs.
To export Java packages, a bundle uses the
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: helloworld
Export-Package: manning.osgi.helloworld
In this case, the bundle helloworld is exportin
package manning.osgi.helloworld.
To import a Java package, a bundle uses the
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: manning.osgi.client
Import-Package: manning.osgi.helloworld
The bundle helloworld.client is importin
manning.osgi.helloworld.
orld is exporting all of its public classes located in the
orld.
bundle uses the manifest header Import-Package:
.osgi.client
.helloworld
nt is importing all public classes in the package
e
d
n
-
r
d
-
of
problem? That is, have we prohibited other classes
Printer
helloworld
PrinterClient
helloworld.client
Figure 2.3 The bundle helloworld includes the
Printer class. The bundle helloworld.client
includes the PrinterClient class.
the bundle helloworld is exporting all of its public classes located in the
ning.osgi.helloworld.
t a Java package, a bundle uses the manifest header Import-Package:
rsion: 1.0
festVersion: 2
olicName: manning.osgi.client
age: manning.osgi.helloworld
helloworld.client is importing all public classes in the package
i.helloworld.
d be clear, we have
s, helloworld and
client, as shown in
The bundle hello-
udes the Printer
bundle helloworld
ludes the Printer-
which makes use of
class.
solved our initial problem? That is, have we prohibited other classes
Printer
helloworld
PrinterClient
helloworld.client
Figure 2.3 The bundle helloworld includes the
Printer class. The bundle helloworld.client
includes the PrinterClient class.
Wednesday, August 28, 13
14. All Content and Rights Reserved (2013)
Modules in OSGi
CHAPTER 2 An OSGi framework primer
In OSGi, you accomplish this by having the provider bundle export the Java packages
that are meant to be shared, and then have the consumer bundle import the Java
packages that it needs.
To export Java packages, a bundle uses the manifest header Export-Package:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: helloworld
Export-Package: manning.osgi.helloworld
In this case, the bundle helloworld is exporting all of its public classes located in the
package manning.osgi.helloworld.
To import a Java package, a bundle uses the manifest header Import-Package:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: manning.osgi.client
Import-Package: manning.osgi.helloworld
The bundle helloworld.client is importing all public classes in the package
manning.osgi.helloworld.
As should be clear, we have
two bundles, helloworld and
helloworld.client, as shown in
figure 2.3. The bundle hello-
Printer
helloworld
PrinterClient
helloworld.client
20 CHAPTER 2 An OSGi framew
In OSGi, you accomplish this by having the pro
that are meant to be shared, and then have
packages that it needs.
To export Java packages, a bundle uses the
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: helloworld
Export-Package: manning.osgi.helloworld
In this case, the bundle helloworld is exportin
package manning.osgi.helloworld.
To import a Java package, a bundle uses the
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: manning.osgi.client
Import-Package: manning.osgi.helloworld
The bundle helloworld.client is importin
manning.osgi.helloworld.
orld is exporting all of its public classes located in the
orld.
bundle uses the manifest header Import-Package:
.osgi.client
.helloworld
nt is importing all public classes in the package
e
d
n
-
r
d
-
of
problem? That is, have we prohibited other classes
Printer
helloworld
PrinterClient
helloworld.client
Figure 2.3 The bundle helloworld includes the
Printer class. The bundle helloworld.client
includes the PrinterClient class.
the bundle helloworld is exporting all of its public classes located in the
ning.osgi.helloworld.
t a Java package, a bundle uses the manifest header Import-Package:
rsion: 1.0
festVersion: 2
olicName: manning.osgi.client
age: manning.osgi.helloworld
helloworld.client is importing all public classes in the package
i.helloworld.
d be clear, we have
s, helloworld and
client, as shown in
The bundle hello-
udes the Printer
bundle helloworld
ludes the Printer-
which makes use of
class.
solved our initial problem? That is, have we prohibited other classes
Printer
helloworld
PrinterClient
helloworld.client
Figure 2.3 The bundle helloworld includes the
Printer class. The bundle helloworld.client
includes the PrinterClient class.
Wednesday, August 28, 13
15. All Content and Rights Reserved (2013)
Validation
OtherClientprint()
Printer
printMyMessage()
PrinterClientprint()
import manning.osgi.helloworld.client;
...
new PrinterClient().printMyMessage();
...
Wednesday, August 28, 13
16. All Content and Rights Reserved (2013)
Validation
OtherClientprint()
Printer
printMyMessage()
PrinterClientprint()
import manning.osgi.helloworld.client;
...
new PrinterClient().printMyMessage();
...
org.osgi.framework.BundleException: Unresolved
constraint in bundle: package;
(package=manning.osgi.helloworld.client)
Wednesday, August 28, 13
17. All Content and Rights Reserved (2013)
Validation
Class<?> printerClientClass =
Class.forName("manning.osgi.helloworld.client.PrinterClient");
Object printerClientInstance =
printerClientClass.newInstance();
Method printMethod =
printerClientClass.getMethod("printMyMessage");
printMethod.invoke(printerClientInstance);
Wednesday, August 28, 13
18. All Content and Rights Reserved (2013)
Validation
Class<?> printerClientClass =
Class.forName("manning.osgi.helloworld.client.PrinterClient");
Object printerClientInstance =
printerClientClass.newInstance();
Method printMethod =
printerClientClass.getMethod("printMyMessage");
printMethod.invoke(printerClientInstance);
org.osgi.framework.BundleException: Unresolved
constraint in bundle: package;
(package=manning.osgi.helloworld.client)
Wednesday, August 28, 13
19. All Content and Rights Reserved (2013)
Advantages
✤ Formal contract between providers/consumers of interfaces
✤ Declarative and not intrusive
✤ Versioned
✤ Unit of reuse and management
✤ Has own life-cycle
, and then have the consumer bundle import the Java
a bundle uses the manifest header Export-Package:
world
gi.helloworld
oworld is exporting all of its public classes located in the
oworld.
a bundle uses the manifest header Import-Package:
ng.osgi.client
gi.helloworld
ient is importing all public classes in the package
have
and
n in
lo-
ter
rld
Printer
helloworld
PrinterClient
helloworld.client
Figure 2.3 The bundle helloworld includes the
meant to be shared, and then have the consumer bundle import the Java
s that it needs.
xport Java packages, a bundle uses the manifest header Export-Package:
t-Version: 1.0
ManifestVersion: 2
SymbolicName: helloworld
Package: manning.osgi.helloworld
ase, the bundle helloworld is exporting all of its public classes located in the
manning.osgi.helloworld.
mport a Java package, a bundle uses the manifest header Import-Package:
t-Version: 1.0
ManifestVersion: 2
SymbolicName: manning.osgi.client
Package: manning.osgi.helloworld
ndle helloworld.client is importing all public classes in the package
.osgi.helloworld.
hould be clear, we have
ndles, helloworld and
rld.client, as shown in
2.3. The bundle hello-
includes the Printer
he bundle helloworld
Printer
helloworld
PrinterClient
helloworld.client
Figure 2.3 The bundle helloworld includes the
manning.osgi.helloworld
Wednesday, August 28, 13
20. All Content and Rights Reserved (2013)
✤ Data encapsulation
✤ Dealing with changes
✤ Extensibility
✤ Building infrastructures
Agenda
Modularization Grade
Wednesday, August 28, 13
21. All Content and Rights Reserved (2013)
Dealing with Changes
"but in the world nothing can be said to be
certain except death and taxes."
- Ben Franklin
Wednesday, August 28, 13
22. All Content and Rights Reserved (2013)
Interface Changes
package manning.osgi.helloworld;
import java.io.PrintStream;
public class Printer
{
public void println(PrintStream stream, String message)
{
stream.println(message);
}
}
Wednesday, August 28, 13
23. All Content and Rights Reserved (2013)
Interface Changes
java.lang.NoSuchMethodError:
manning.osgi.helloworld.Printer.print(Ljava/
lang/String;)V
bundle uses the manifest header Import-Package:
osgi.client
helloworld
nt is importing all public classes in the package
e
d
n
-
r
d
-
of
problem? That is, have we prohibited other classes
ent class? Yes, by not exporting the package
ent, we make sure that no other class outside the
Printer
helloworld
PrinterClient
helloworld.client
Figure 2.3 The bundle helloworld includes the
Printer class. The bundle helloworld.client
includes the PrinterClient class.
t a Java package, a bundle uses the manifest header Import-Package:
rsion: 1.0
festVersion: 2
olicName: manning.osgi.client
age: manning.osgi.helloworld
helloworld.client is importing all public classes in the package
i.helloworld.
d be clear, we have
, helloworld and
client, as shown in
The bundle hello-
udes the Printer
bundle helloworld
udes the Printer-
which makes use of
class.
solved our initial problem? That is, have we prohibited other classes
the PrinterClient class? Yes, by not exporting the package
i.helloworld.client, we make sure that no other class outside the
Printer
helloworld
PrinterClient
helloworld.client
Figure 2.3 The bundle helloworld includes the
Printer class. The bundle helloworld.client
includes the PrinterClient class.
Wednesday, August 28, 13
24. All Content and Rights Reserved (2013)
Versioning
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: helloworld
Bundle-Version: 1.1
Export-Package: manning.osgi.helloworld;version=1.1
port a Java package, a bundle uses the manifest header Import-Package:
-Version: 1.0
anifestVersion: 2
ymbolicName: manning.osgi.client
ackage: manning.osgi.helloworld
dle helloworld.client is importing all public classes in the package
osgi.helloworld.
ould be clear, we have
dles, helloworld and
ld.client, as shown in
3. The bundle hello-
ncludes the Printer
e bundle helloworld
includes the Printer-
ass, which makes use of
er class.
we solved our initial problem? That is, have we prohibited other classes
ng the PrinterClient class? Yes, by not exporting the package
osgi.helloworld.client, we make sure that no other class outside the
ld.client bundle can use it.
Printer
helloworld
PrinterClient
helloworld.client
Figure 2.3 The bundle helloworld includes the
Printer class. The bundle helloworld.client
includes the PrinterClient class.
Wednesday, August 28, 13
25. All Content and Rights Reserved (2013)
Versioning
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: manning.osgi.anotherclient
Bundle-Version: 1.0.0
Import-Package:
manning.osgi.helloworld;version="[1.1,1.1.9]"
helloworld.anotherclient
Wednesday, August 28, 13
26. All Content and Rights Reserved (2013)
Versioning
helloworld
1.1.0
helloworld
0.0.0
helloworld.client
helloworld.anotherclient
Wednesday, August 28, 13
27. All Content and Rights Reserved (2013)
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: helloworld
Export-Package: manning.osgi.helloworld
In this case, the bundle helloworld is exporting all of its publ
package manning.osgi.helloworld.
To import a Java package, a bundle uses the manifest heade
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: manning.osgi.client
Import-Package: manning.osgi.helloworld
The bundle helloworld.client is importing all public c
manning.osgi.helloworld.
As should be clear, we have
two bundles, helloworld and
helloworld.client, as shown in
figure 2.3. The bundle hello-
world includes the Printer
class. The bundle helloworld
Printer
helloworld
Figure 2.3 The bundle hello
Versioning
Bundle-SymbolicName: helloworld
Bundle-Version: 1.1
ge, a bundle uses the manifest header Import-Package:
2
ning.osgi.client
osgi.helloworld
.client is importing all public classes in the package
d.
e have
d and
own in
hello-
rinter
oworld
inter-
use of
nitial problem? That is, have we prohibited other classes
erClient class? Yes, by not exporting the package
d.client, we make sure that no other class outside the
Printer
helloworld
PrinterClient
helloworld.client
Figure 2.3 The bundle helloworld includes the
Printer class. The bundle helloworld.client
includes the PrinterClient class.
Bundle ID:
symbolicName + version
1.0
1.1
Wednesday, August 28, 13
28. All Content and Rights Reserved (2013)
Versioning: details
First, we’ll create a new version of the helloworld b
a new bundle JAR file, which we’ll name helloworld_
JAR filename has no implications at runtime and does
ber. Bundle helloworld_1.1.0.jar has the same bundle
as bundle helloworld.jar. But, in addition, the bundle
number . number . number . (alphanumeric | '_' | '-' )+
Major Minor Micro er
Figure 2.4
four parts: m
first three t
takes alpha
zero is used
Version
Version specifications are used in several places. A version has the following grammar:
version ::=
major( '.' minor ( '.' micro ( '.' qualifier )? )? )?
major ::= number // See 1.3.2
minor ::= number
micro ::= number
qualifier ::= ( alphanum | ._. | '-' )+
A version must not contain any white space. The default value for a version is 0.0.0.
Version Ranges
A version range describes a range of versions using a mathematical interval notation. See [1
matical Convention for Interval Notation.
The syntax of a version range is:
version-range ::= interval | atleast
interval ::= ( '[' | '(' ) floor ',' ceiling ( ']' | ')' )
atleast ::= version
floor ::= version
ceiling ::= version
If a version range is specified as a single version, it must be interpreted as the range [version
default for a non-specified version range is 0, which maps to [0.0.0,∞).
Wednesday, August 28, 13
29. All Content and Rights Reserved (2013)
Versioning: details
dles
In the following table, for each specified range in the le
a member of the range if the predicate in the right-han
7 Filter Syntax
The OSGi specifications use filter expressions extensiv
description of a constraint.
Table 3.1 Examples of version ranges
Example Predicate
[1.2.3, 4.5.6) 1.2.3 <= x < 4.5.6
[1.2.3, 4.5.6] 1.2.3 <= x <= 4.5.6
(1.2.3, 4.5.6) 1.2.3 < x < 4.5.6
(1.2.3, 4.5.6] 1.2.3 < x <= 4.5.6
1.2.3 1.2.3 <= x
versão [versão, ∞)
(vazio) [0.0.0, ∞)
Wednesday, August 28, 13
30. All Content and Rights Reserved (2013)
Advantages
✤ Automatically maintains older versions while they are being used:
✤ For example, even after uninstalling helloworld:0.0, it is kept while
helloworld.client references to it.
✤ If helloworld.client is removed and there are no other references to
helloworld:0.0, then it is also removed.
✤ Allows the simultaneous use of different versions of the same
software component
✤ For example, different versions of commons logging in the same
runtime
Wednesday, August 28, 13
31. All Content and Rights Reserved (2013)
Implementation Changes
✤ In general, things are less ‘drastic’ and only involve implementation
changes
✤ For example, include date in Printer.print()
✤ Implementation changes must be transparent to consuming clients
✤ Re-compilation of client should not be needed
✤ Should be incorporated dynamically
✤ SERVICE ORIENTED IMPLEMENTATION
Wednesday, August 28, 13
32. All Content and Rights Reserved (2013)
Implementation Changes
Previously, we ran into a scenario where we needed to change the interface of a bun-
dle. Life isn’t always so dramatic, and most commonly you may need to change the
implementation of a bundle and not its exposed interface.
Let’s look again at our first version of the Printer class, from section 2.1. We’d like
to change it, as shown in the following listing, so that each printed message gets time-
stamped with the current time.
package manning.osgi.helloworld;
import java.text.DateFormat;
import java.util.Date;
public class Printer {
private static final String SEPARATOR = ": ";
public void print(String message) {
System.out.println(getCurrentTime() + SEPARATOR + message);
}
private String getCurrentTime() {
return DateFormat.getTimeInstance(DateFormat.LONG).
format(new Date());
}
}
You know the drill. Create a new version of bundle helloworld, and then as usual pro-
vision it in Felix. Here’s where it starts getting interesting. When would the existing
client bundles pick up this new version? For bundle helloworld.client to be able to
Listing 2.5 The Printer service implementation
Wednesday, August 28, 13
33. All Content and Rights Reserved (2013)
Implementation Changes
Previously, we ran into a scenario where we needed to change the interface of a bun-
dle. Life isn’t always so dramatic, and most commonly you may need to change the
implementation of a bundle and not its exposed interface.
Let’s look again at our first version of the Printer class, from section 2.1. We’d like
to change it, as shown in the following listing, so that each printed message gets time-
stamped with the current time.
package manning.osgi.helloworld;
import java.text.DateFormat;
import java.util.Date;
public class Printer {
private static final String SEPARATOR = ": ";
public void print(String message) {
System.out.println(getCurrentTime() + SEPARATOR + message);
}
private String getCurrentTime() {
return DateFormat.getTimeInstance(DateFormat.LONG).
format(new Date());
}
}
You know the drill. Create a new version of bundle helloworld, and then as usual pro-
vision it in Felix. Here’s where it starts getting interesting. When would the existing
client bundles pick up this new version? For bundle helloworld.client to be able to
Listing 2.5 The Printer service implementation
Interface and
implementation
dependency
Wednesday, August 28, 13
34. All Content and Rights Reserved (2013)
Services in OSGiIn these roles, the OSGi service registry acts as the mediator, isolating the provider
from the requestor. The service provider bundle owns the service interface, service
properties, and service implementation. The service requestor bundle uses the service
interface and service properties, but it can’t access the service implementation. A dia-
gram of the OSGi service registry is shown in figure 2.8.
Returning to our example, what do we need to do to change the Printer class into
a Printer service?
2.4.1 The Printer service
First, we must create a service interface for the Printer service. OSGi makes this a sim-
ple task. We’ll just create a Java interface for the Printer class:
package manning.osgi.helloworld;
public interface Printer {
public void print(String message);
}
The Printer service interface is defined by a Java interface with a single println
method. No implementation is needed to define the service interface. Technically, we
could use a Java class rather than a Java interface to define the OSGi service interface.
In this case, the service implementation would extend the Java class instead of imple-
menting the Java interface. But using a Java interface is cleaner, is easier to under-
stand, and keeps coupling between the service provider and the service requestor to a
minimum.
Service
properties
Service
implementation
Service
properties
Figure 2.8 The service provider bundle registers the service interface, service properties,
and service implementation into the OSGi service registry. The service requestor bundle
retrieves the service interface and the service properties from the OSGi service registry. Services and loose coupling
Next, we need a Java object to serve as the service implementation. Versio
the Printer class is almost good enough; we just need to change it so that
ments the service interface, as shown here.
package manning.osgi.helloworld.impl;
import java.text.DateFormat;
import java.util.Date;
import manning.osgi.helloworld.Printer;
public class PrinterImpl implements Printer {
private static final String SEPARATOR = ": ";
public void print(String message) {
System.out.println(getCurrentTime() + SEPARATOR + message);
}
private String getCurrentTime() {
return DateFormat.getTimeInstance(DateFormat.LONG).
format(new Date());
}
}
First, the service implementation must implement (or extend) the service in
Second, it’s important to use a different Java package for the implementati
what is used for the interface. The package used by the interface need
exported, whereas we don’t want to export the package used by the impleme
Otherwise, we might not be able to change the implementation easily witho
stalling the clients.
TIP Use different packages for the service interface and service implemen
Listing 2.6 Upgraded Printer service implementation
Wednesday, August 28, 13
35. All Content and Rights Reserved (2013)
Services in OSGiIn these roles, the OSGi service registry acts as the mediator, isolating the provider
from the requestor. The service provider bundle owns the service interface, service
properties, and service implementation. The service requestor bundle uses the service
interface and service properties, but it can’t access the service implementation. A dia-
gram of the OSGi service registry is shown in figure 2.8.
Returning to our example, what do we need to do to change the Printer class into
a Printer service?
2.4.1 The Printer service
First, we must create a service interface for the Printer service. OSGi makes this a sim-
ple task. We’ll just create a Java interface for the Printer class:
package manning.osgi.helloworld;
public interface Printer {
public void print(String message);
}
The Printer service interface is defined by a Java interface with a single println
method. No implementation is needed to define the service interface. Technically, we
could use a Java class rather than a Java interface to define the OSGi service interface.
In this case, the service implementation would extend the Java class instead of imple-
menting the Java interface. But using a Java interface is cleaner, is easier to under-
stand, and keeps coupling between the service provider and the service requestor to a
minimum.
Service
properties
Service
implementation
Service
properties
Figure 2.8 The service provider bundle registers the service interface, service properties,
and service implementation into the OSGi service registry. The service requestor bundle
retrieves the service interface and the service properties from the OSGi service registry. Services and loose coupling
Next, we need a Java object to serve as the service implementation. Versio
the Printer class is almost good enough; we just need to change it so that
ments the service interface, as shown here.
package manning.osgi.helloworld.impl;
import java.text.DateFormat;
import java.util.Date;
import manning.osgi.helloworld.Printer;
public class PrinterImpl implements Printer {
private static final String SEPARATOR = ": ";
public void print(String message) {
System.out.println(getCurrentTime() + SEPARATOR + message);
}
private String getCurrentTime() {
return DateFormat.getTimeInstance(DateFormat.LONG).
format(new Date());
}
}
First, the service implementation must implement (or extend) the service in
Second, it’s important to use a different Java package for the implementati
what is used for the interface. The package used by the interface need
exported, whereas we don’t want to export the package used by the impleme
Otherwise, we might not be able to change the implementation easily witho
stalling the clients.
TIP Use different packages for the service interface and service implemen
Listing 2.6 Upgraded Printer service implementation
interface implementação
Wednesday, August 28, 13
36. All Content and Rights Reserved (2013)
Services in OSGi
interface implementação
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: helloworld
Bundle-Version: 1.2
Export-Package:
manning.osgi.helloworld;version=1.2
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: helloworld.impl
Bundle-Version: 1.0
Import-Package:
manning.osgi.helloworld;version=1.2
Wednesday, August 28, 13
37. All Content and Rights Reserved (2013)
Services in OSGi
interface implementação
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: helloworld
Bundle-Version: 1.2
Export-Package:
manning.osgi.helloworld;version=1.2
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: helloworld.impl
Bundle-Version: 1.0
Import-Package:
manning.osgi.helloworld;version=1.2
Do not export
implementation
Wednesday, August 28, 13
38. All Content and Rights Reserved (2013)
Services in OSGi
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: helloworld.client
Bundle-Version: 1.0
Import-Package:
manning.osgi.helloworld;version=1.2
interface implementação
cliente
Wednesday, August 28, 13
39. All Content and Rights Reserved (2013)
Services in OSGi
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: helloworld.client
Bundle-Version: 1.0
Import-Package:
manning.osgi.helloworld;version=1.2
Do not import
implementation
interface implementação
cliente
Wednesday, August 28, 13
40. All Content and Rights Reserved (2013)
Service Repository
✤ Our system has three bundles:
✤ helloworld: provides Printer interface
✤ helloworld.impl: provides Printer implementation
✤ helloworld.client: consumes Printer service
✤ Now we need a way of the consumer finding the service itself!
Wednesday, August 28, 13
41. Todos os direitos reservados a Alexandre de Castro Alves / All Content and Rights Reserved (2012)
Service Repository
40 CHAPTER 2 An OSGi framework primer
In these roles, the OSGi service registry acts as the mediator, isolating the provi
from the requestor. The service provider bundle owns the service interface, ser
properties, and service implementation. The service requestor bundle uses the ser
interface and service properties, but it can’t access the service implementation. A
gram of the OSGi service registry is shown in figure 2.8.
Returning to our example, what do we need to do to change the Printer class i
a Printer service?
Service
properties
Requestor Provider
OSGi
service
registry
Register/unregisterRetrieve/release
Service
implementation
Service
interface
Service
properties
Service
interface
Figure 2.8 The service provider bundle registers the service interface, service properties,
and service implementation into the OSGi service registry. The service requestor bundle
retrieves the service interface and the service properties from the OSGi service registry.
✤ OSGi service:
✤ Interface
✤ Implementation
✤ Properties
✤ Providers and consumers
interact through the Service
Repository
Wednesday, August 28, 13
42. All Content and Rights Reserved (2013)
Service Providers42 CHAPTER 2 An OSGi framework primer
package manning.osgi.helloworld.impl;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import manning.osgi.helloworld.Printer;
public class PrinterActivator implements BundleActivator {
private ServiceRegistration serviceRegistration;
public void start(BundleContext bundleContext) throws Exception {
serviceRegistration =
bundleContext.registerService(
Printer.class.getName(),
new PrinterImpl(),
null);
}
public void stop(BundleContext bundleContext) throws Exception {
serviceRegistration.unregister();
}
}
You can archive the Printer interface, the Printer implementation, and the
PrinterActivator classes into version 1.4.0 of the helloworld bundle:
Listing 2.7 Registering the Printer service in the OSGi service registry
Printer service
interface
b
Printer service
implementationc
Unregister
serviced
Wednesday, August 28, 13
43. All Content and Rights Reserved (2013)
Service Providers42 CHAPTER 2 An OSGi framework primer
package manning.osgi.helloworld.impl;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import manning.osgi.helloworld.Printer;
public class PrinterActivator implements BundleActivator {
private ServiceRegistration serviceRegistration;
public void start(BundleContext bundleContext) throws Exception {
serviceRegistration =
bundleContext.registerService(
Printer.class.getName(),
new PrinterImpl(),
null);
}
public void stop(BundleContext bundleContext) throws Exception {
serviceRegistration.unregister();
}
}
You can archive the Printer interface, the Printer implementation, and the
PrinterActivator classes into version 1.4.0 of the helloworld bundle:
Listing 2.7 Registering the Printer service in the OSGi service registry
Printer service
interface
b
Printer service
implementationc
Unregister
serviced
We will take a look at
the BundleActivator
and the BundleContext
later
Wednesday, August 28, 13
44. All Content and Rights Reserved (2013)
Service Consumers
public void start(BundleContext bundleContext) throws Exception {
this.bundleContext = bundleContext;
serviceReference =
bundleContext.getServiceReference(Printer.class.getName());
if (serviceReference != null) {
Printer printer = (Printer)
bundleContext.getService(serviceReference);
if (printer != null) {
printer.print("Hello...");
}
}
}
Wednesday, August 28, 13
45. All Content and Rights Reserved (2013)
Advantages
vant to their tasks. For example, they don’t even have to know about other entities
we’ve discussed, such as auditors.
NOTE Modular systems are composed of modules that yield simple, highly
cohesive interfaces.
Furthermore, we’re able to leverage the OSGi service layer; we had to implement only
a few lines of code to retrieve an auction service that had the proper terms, such as the
proper style and duration.
Albeit being somewhat obvious, we can use the OSGi service registry as a general
registry of application services and thus implement a common design pattern known
as the registry design pattern, shown in figure 3.4.
Registry design pattern
Intent—Allows a consumer to find a service by knowing only its name or some attribute
of the service
Participants—Consuming bundle, Registry service, Provider bundle
Structure—Consuming bundle searches the registry using a name or attributes for a
particular service that has been registered by a provider bundle
Consequences—Consuming bundle doesn't know who provides the services or care how
Known uses—Data source service (see chapter 8)
Related patterns—Whiteboard pattern
Application
bundle
Service
OSGi
service
registry
Provider
bundle
Retrieve Register
Figure 3.4 In the registry design pattern, the application bundle retrieves the application service from
the OSGi service registry, and the providing bundle registers the service objects.
✤ Clear separation of concerns between providers and consumers
✤ Dynamic
✤ Change of implementation without impacting consumer
✤ Service Repository
Wednesday, August 28, 13
46. All Content and Rights Reserved (2013)
✤ Data encapsulation
✤ Dealing with changes
✤ Extensibility
✤ Building infrastructures
Agenda
Modularization Grade
Wednesday, August 28, 13
47. All Content and Rights Reserved (2013)
Extensibility
"Technology does not drive change - it
enables change."
- Unknown
Wednesday, August 28, 13
48. All Content and Rights Reserved (2013)
Service Selection
being exchanged with other parties. A user can
the message.
Hash functions used for this purpose have th
sages that differ will have the same hash value. T
sage and its hash value to a receiver, which can
the received message. The generated hash valu
only if the message has not been altered.
We can define our fingerprint service as follo
public interface FingerprintService {
byte [] hash(String input);
}
There are several implementations of hash func
and MD5 algorithms, both invented by Rivest.
attacks for it, whereas MD5 is slower but safer. M
differences; they just want to get some default
bly be MD5. When dealing with security, we alw
users who may be more educated on the subjec
rithm. How do you solve this problem in the OS
First of all, you should register these two diffe
ing some additional service property that high
you can define a PERFORMANCE property whose
MD4 MD5
Rápido
Segurança baixa
Devagar
Segurança alta
FingerprintService
Fast
Less secure
Slow
More secure
Wednesday, August 28, 13
49. All Content and Rights Reserved (2013)
Service Selection
MD4 MD5
Rápido
Segurança baixa
Devagar
Segurança alta
FingerprintService
Diferent policies per
customer
Fast
Less secure
Slow
More secure
Wednesday, August 28, 13
50. All Content and Rights Reserved (2013)
Service Properties
Dictionary<String, Object> md5Properties =
new Hashtable<String, Object>();
md5Properties.put("PERFORMANCE", "SLOW");
md5Properties.put("ALGORITHM", "MD5");
md5Properties.put("SECURITY_LEVEL", "HIGH");
registration = bundleContext.registerService(
FingerprintService.class.getName(),
MD5FingerprintServiceImpl,
md5Properties
);
Dictionary<String, Object> md4Properties =
new Hashtable<String, Object>();
md4Properties.put("PERFORMANCE", "FAST");
md4Properties.put("ALGORITHM", "MD4");
md4Properties.put("SECURITY_LEVEL", "MEDIUM");
registration = bundleContext.registerService(
FingerprintService.class.getName(),
MD4FingerprintServiceImpl,
md4Properties
);
Properties associated
to FingerprintService
Service properties are key-
value pairs
Wednesday, August 28, 13
51. All Content and Rights Reserved (2013)
Filters
String filter =
"(&(objectClass=manning.osgi.fingerprint.FingerprintService)" +
" (PERFORMANCE=FAST)" +
")";
ServiceReference[] serviceReferences =
bundleContext.getServiceReferences(null, filter);
if (serviceReferences != null)
{
FingerprintService service =
(FingerprintService) bundleContext.getService(serviceReferences[0]);
//
}
Service filters specified
as in LDAP
Wednesday, August 28, 13
52. All Content and Rights Reserved (2013)
LDAP
sively binary and are specified in prefix form, so you can associate any numbe
operations with them. The last operator is unary as expected; that is, it modifies a
gle operation.
The parse tree shown in figure 4.14 describes an OSGi filter that verifies if all
conditions are met.
You can associate several operations together using a single expression opera
For example, consider the following Java expression:
if ((attr1 == value1) && (attr2 == value2) && (attr3 == value3)) { … }
This can be expressed using the following OSGi filter:
(&(attr1=value1)(attr2=value2)(attr3=value3))
Also, the slightly more complicated Java expression,
if ((attr1 == value1) && ((attr2 == value2) || (attr3 == value3))) { … }
can be expressed using the following OSGi filter:
(&(attr1=value1)(|(attr2=value2)(attr3=value3)))
So there you have it; you’re now an expert on the OSGi filter syntax. Don’t feel
though if you still prefer the infix style, such as that used in Java, instead of the pr
style used here. You’re not alone.
In the next section, we’ll look at how to distinguish services that share the sa
tion (not) operator (!). The first two operators, contrary to the norm
sively binary and are specified in prefix form, so you can associate
operations with them. The last operator is unary as expected; that is, i
gle operation.
The parse tree shown in figure 4.14 describes an OSGi filter that v
conditions are met.
You can associate several operations together using a single expre
For example, consider the following Java expression:
if ((attr1 == value1) && (attr2 == value2) && (attr3 == value3))
This can be expressed using the following OSGi filter:
(&(attr1=value1)(attr2=value2)(attr3=value3))
Also, the slightly more complicated Java expression,
if ((attr1 == value1) && ((attr2 == value2) || (attr3 == value3)
can be expressed using the following OSGi filter:
(&(attr1=value1)(|(attr2=value2)(attr3=value3)))
So there you have it; you’re now an expert on the OSGi filter syntax.
though if you still prefer the infix style, such as that used in Java, inste
style used here. You’re not alone.
In the next section, we’ll look at how to distinguish services that
tion (not) operator (!). The first two operators, contrary to the norm, aren’t exc
sively binary and are specified in prefix form, so you can associate any number
operations with them. The last operator is unary as expected; that is, it modifies a s
gle operation.
The parse tree shown in figure 4.14 describes an OSGi filter that verifies if all t
conditions are met.
You can associate several operations together using a single expression operat
For example, consider the following Java expression:
if ((attr1 == value1) && (attr2 == value2) && (attr3 == value3)) { … }
This can be expressed using the following OSGi filter:
(&(attr1=value1)(attr2=value2)(attr3=value3))
Also, the slightly more complicated Java expression,
if ((attr1 == value1) && ((attr2 == value2) || (attr3 == value3))) { … }
can be expressed using the following OSGi filter:
(&(attr1=value1)(|(attr2=value2)(attr3=value3)))
So there you have it; you’re now an expert on the OSGi filter syntax. Don’t feel b
though if you still prefer the infix style, such as that used in Java, instead of the pre
style used here. You’re not alone.
tion (not) operator (!). The first two operators, contrary to the norm
sively binary and are specified in prefix form, so you can associate
operations with them. The last operator is unary as expected; that is, i
gle operation.
The parse tree shown in figure 4.14 describes an OSGi filter that v
conditions are met.
You can associate several operations together using a single expre
For example, consider the following Java expression:
if ((attr1 == value1) && (attr2 == value2) && (attr3 == value3))
This can be expressed using the following OSGi filter:
(&(attr1=value1)(attr2=value2)(attr3=value3))
Also, the slightly more complicated Java expression,
if ((attr1 == value1) && ((attr2 == value2) || (attr3 == value3)
can be expressed using the following OSGi filter:
(&(attr1=value1)(|(attr2=value2)(attr3=value3)))
So there you have it; you’re now an expert on the OSGi filter syntax.
though if you still prefer the infix style, such as that used in Java, inste
infix (e.g. Java)
prefix
Wednesday, August 28, 13
53. All Content and Rights Reserved (2013)
LDAP
✤ Comparison operators:
✤ =, >=, <=, ~= (approximation), =* (existence)
✤ Logical operators:
✤ & (conjunction)
✤ | (disjunction)
✤ ! (negation)
✤ Lists: true if matches at least one element
Wednesday, August 28, 13
54. All Content and Rights Reserved (2013)
Service Priority
MD4 MD5
Rápido
Segurança baixa
Devagar
Segurança alta
FingerprintService
Which service to use?
Fast
Less secure
Slow
More secure
Wednesday, August 28, 13
55. All Content and Rights Reserved (2013)
Service Priority
MD4 MD5
Rápido
Segurança baixa
Devagar
Segurança alta
FingerprintService
Which service to use?
Selection is not
deterministic
Fast
Less secure
Slow
More secure
Wednesday, August 28, 13
56. All Content and Rights Reserved (2013)
Service Priority
MD4 MD5
Rápido
Segurança baixa
Devagar
Segurança alta
FingerprintService
Which service to use?
Selection is not
deterministic
Use priorities to make
selection deterministic.
For example, select
safest algorithm by
default
Fast
Less secure
Slow
More secure
Wednesday, August 28, 13
57. All Content and Rights Reserved (2013)
Service Priority
119Decoupling bundles using services
In this case, you want to avoid this nondeterminism; you’d like the MD5 service
implementation to have priority over the MD4 implementation. This can be done
through the use of the predefined SERVICE_RANKING property, whose value is of type
Integer. When multiple qualifying service implementations exist, the OSGi frame-
work selects the one with the highest SERVICE_RANKING property, as shown in the fol-
lowing listing.
Dictionary<String, Object> md5Properties =
new Hashtable<String, Object>();
md5Properties.put("PERFORMANCE", "SLOW");
md5Properties.put("ALGORITHM", "MD5");
md5Properties.put("SECURITY_LEVEL", "HIGH");
md5Properties.put(Constants.SERVICE_RANKING, 10);
registration = bundleContext.registerService(
FingerprintService.class.getName(),
MD5FingerprintServiceImpl,
md5Properties
);
Dictionary<String, Object> md4Properties =
new Hashtable<String, Object>();
md4Properties.put("PERFORMANCE", "FAST");
md4Properties.put("ALGORITHM", "MD4");
md4Properties.put("SECURITY_LEVEL", "MEDIUM");
md4Properties.put(Constants.SERVICE_RANKING, 5);
registration = bundleContext.registerService(
FingerprintService.class.getName(),
MD4FingerprintServiceImpl,
md4Properties
);
The MD5 service implementation has a service ranking of 10 B, whereas the MD4 ser-
vice implementation has a ranking of 5 c. Thus the OSGi framework selects the MD5
Listing 4.7 Service rankings for the fingerprint service
Higher service
priorityb
Lower service
priorityc
Wednesday, August 28, 13
58. Todos os direitos reservados a Alexandre de Castro Alves / All Content and Rights Reserved (2012)
Plugins
✤ How to add new security
algorithms for the Fingerprint
application?
✤ We need a systematic approach
to support application plugins.
Wednesday, August 28, 13
60. All Content and Rights Reserved (2013)
Whiteboard design pattern
✤ Application looks for all registered FingerprintService services
✤ Out-of-the-box: MD4, MD5
ServiceReference[] serviceReferences =
bundleContext.getAllServiceReferences(
FingerprintService.class.getName(), null);
Wednesday, August 28, 13
61. All Content and Rights Reserved (2013)
Whiteboard design pattern
✤ Next, application registers to be notified when a new service is added
or removed dynamically
String filter = "(objectClass="
+ FingerprintService.class.getName() + ")";
bundleContext.addServiceListener(new MyServiceListener(bundleContext),
filter);
Wednesday, August 28, 13
62. All Content and Rights Reserved (2013)
ServiceListener
public class MyServiceListener implements ServiceListener {
private BundleContext bundleContext;
private Map<String, FingerprintService> services =
new HashMap<String, FingerprintService>();
public MyServiceListener(BundleContext bundleContext) {
this.bundleContext = bundleContext;
}
public void serviceChanged(ServiceEvent serviceEvent) {
ServiceReference ref =
serviceEvent.getServiceReference();
switch (serviceEvent.getType()) {
case ServiceEvent.REGISTERED: {
FingerprintService newService =
(FingerprintService) bundleContext.getService(ref);
services.put((String) ref.getProperty("ALGORITHM"), newService);
break;
}
case ServiceEvent.UNREGISTERING: {
services.remove((String) ref.getProperty("ALGORITHM"));
break;
}
}
}
Wednesday, August 28, 13
63. All Content and Rights Reserved (2013)
Whiteboard design pattern
✤ Providers (Bundle Plugin) simply register new service
implementations as needed
✤ It is not necessary for provider (plugin) to learn any new API
properties.put("PERFORMANCE", "SLOW");
properties.put("ALGORITHM", "MD6");
properties.put("SECURITY_LEVEL", "HIGHEST");
registration = bundleContext.registerService(
FingerprintService.class.getName(),
MD6FingerprintServiceImpl,
properties
);
Wednesday, August 28, 13
64. All Content and Rights Reserved (2013)
Advantages
✤ OSGi’s service architecture allows one to create applications that can
be systematically extended
✤ Service properties
✤ Service selection and filtering
✤ Whiteboard design-pattern
✤ The onus of extensibility lies on infrastructure and not on plugin
Wednesday, August 28, 13
65. All Content and Rights Reserved (2013)
✤ Data encapsulation
✤ Dealing with changes
✤ Extensibility
✤ Building infrastructures
Agenda
Modularization Grade
Wednesday, August 28, 13
66. All Content and Rights Reserved (2013)
Building infrastructures
"Ah, to build, to build! That is the noblest art
of all arts."
- Henry Longfellow, 1807
Wednesday, August 28, 13
67. All Content and Rights Reserved (2013)
The OSGi Platform
7The OSGi technology
guration Admin Declarative serviceDeployment Admin
User-defined services and applications
OSGI framework
OSGI service platform
Java
Dynamic Java modules (bundles)
Service management
Figure 1.5 The OSGi Service Platform comprises the OSGi framework and the OSGI services.
✤ A modular platform in itself
✤ OSGi has several layers:
✤ The framework, the core services, the optional services, and the application layer
Wednesday, August 28, 13
68. Todos os direitos reservados a Alexandre de Castro Alves / All Content and Rights Reserved (2012)
The OSGi Framework
✤ Execution environment:
✤ Java SE, Java ME, e other
environments
✤ Module, Lifecycle layers
✤ Bundles
✤ BundleContext
✤ Service layer
✤ OSGi services
function normally, but now it uses the new Printer service implementation. Congrat-
ulations, you changed the implementation of a running application!
This simple hello world application allowed us to investigate several important fea-
tures from OSGi, ranging from versioning, to package restriction and accessibility, to
service management. In the next section, we’ll discuss the role of these features in the
overall architecture of the OSGi framework.
2.5 The OSGi layered architecture
The OSGi framework is implemented
using a layered architecture,
depicted in figure 2.11.
The bottom layer is the execution
environment. Even though the OSGi
framework is running on top of a
JVM, the JVM itself can have different
versions and profiles. For instance,
there’s a Java Micro Edition of the
JVM, which is named Java ME; there’s
also a Java Standard Edition and a
Java Enterprise Edition. On top of
that, each edition may have several
versions, such as Java SE 1.5 and 1.6.
Because the developer can be using
bundles provided by different ven-
Execution environment
Module layer
Lifecycle layer
Service layer
Security
Figure 2.11 OSGi’s layered architecture is
composed of four layers: the execution environment,
the module layer, the lifecycle layer, and the serviceWednesday, August 28, 13
69. Todos os direitos reservados a Alexandre de Castro Alves / All Content and Rights Reserved (2012)
Optional Services
✤ Residencial
✤ Enterprise
✤ Management
✤ Configuration
✤ Distribution
✤ Data Access
Examples of enterprise features, as shown in figure 1.6, are the following:
I Management and configuration—This group includes the Configuration A
service as well as the JMX Management Model service and the Metatype se
I Distribution—This feature allows the communication of end points bet
remote instances of OSGi framework instances. Some of the services in
group are the Remote Service and the SCA Configuration Type.
I Data access—This feature includes support for JDBC, JPA, and JTA and allow
manipulation of persisted objects.
Before getting into the details of the OSGi technology itself, you should under
the high-level benefits of using OSGi as your development platform. We addres
topic in the next section.
OSGi framework
JMX
Metatype Admin
guration Admin
guration
JTA
JPA
JDBC
Data access
DistributionRemote service SCA
Figure 1.6 Enterprise OSGi consists of the OSGi framework and several OSGi services;
together they provide enterprise features.
Wednesday, August 28, 13
70. All Content and Rights Reserved (2013)
Core Services
✤ Permission Admin Service
✤ URL Handlers Service
✤ Resolver Hook Service
✤ Bundle Hook Service
✤ Service Hook Service
✤ Weaving Hook
Wednesday, August 28, 13
71. All Content and Rights Reserved (2013)
Enterprise OSGi & JEE
✤ OSGi makes use of several JEE standards:
✤ HTTP Servlets, JMX, JNDI, JTA, JPA, JDBC, JCA, etc
✤ Specific modifications needed to conform to the OSGi environment, for
example, such as the removal of static elements
✤ Also uses other enterprise specifications:
✤ SCA (Software Component Architecture)
✤ And defines some of its own:
✤ Meta-type, Configuration, etc.
Wednesday, August 28, 13
72. All Content and Rights Reserved (2013)
Implementations
✤ Framework
✤ Eclipse Equinox
✤ Apache Felix
✤ Knopflerfish
✤ Enterprise
✤ Eclipse Gemini/Virgo
✤ Apache Aries
Wednesday, August 28, 13
73. All Content and Rights Reserved (2013)
Next, you need to install the helloworld and helloworld.client bundles into the
framework.
We have two bundles, or JAR files: helloworld.jar and helloworld.client.jar. The
archived content of the helloworld.jar bundle is
META-INF/MANIFEST.MF
manning/osgi/helloworld/Printer.class
And for the helloworld.client.jar, it’s
META-INF/MANIFEST.MF
manning/osgi/helloworld/client/PrinterClient.class
manning/osgi/helloworld/client/PrinterClientActivator.class
Copy helloworld.jar and helloworld.client.jar to the Felix installation to make it easier
to reference the files. Create a dist directory underneath the install directory, and
place the JAR files there.
NOTE Don’t place the hello world bundles in the bundle directory, because
this directory is by default configured as Felix’s autodeploy directory, a fea-
ture that we’ll talk about in later chapters.
Now, you can install these bundles with the install command typed in the Felix shell:
g! felix:install file:dist/helloworld.jar
Bundle ID: 5
g! felix:install file:dist/helloworld.client.jar
Bundle ID: 6
Each time you install a bundle, Felix provides a unique bundle ID, which is needed
later by the other commands.
NOTE The Gogo shell commands, such as felix:install, can be specified
without the prefix (that is, felix, obr, gogo) if they’re unique. But generally
it’s good to keep the prefix because it helps with backward compatibility for
future versions of Felix.
Did you expect to see “Hello World” printed? We’re almost there.
Felix
✤ Bootstrap
23Running and testing OSGi
Open a shell, and change directory to Felix’s installation home. You can run Felix
with the following command:
felix-framework-3.0.6$ java -jar bin/felix.jar
____________________________
Welcome to Apache Felix Gogo
g!
Conventions
Before we continue, here are some assumptions and conventions you should know:
I We’ll assume that the Java program is in your shell’s path. This is generally the
case.
I We’ll be using JDK 1.5.0_16 to run the examples.
I We’ll be using UNIX commands, as executed in a bash shell, as the convention.
Thanks to Java, we’re mostly isolated from the operating system, except for a
few file-related commands.
I If you’re using Windows, you may have to replace the forward slash (/) with a
backward slash () in file-related commands. As an example, this command,
java -jar bin/felix.jar
should be changed to the following in a Windows environment:
✤ Installing bundles
✤ Activating bundles
CHAPTER 2 An OSGi framework primer
4 Starting the bundles in Felix
To start a bundle, you must use the start command in the Felix shell. As expected,
the start command triggers the BundleActivator.start() callback. Let’s try it out:
g! felix:start 4
g! felix:start 5
Note that you must use the ID returned by the install command.
You should get a stack trace and still no “Hello World” message, which probably
isn’t what you expected. If you go down the stack, you’ll eventually notice the follow-Wednesday, August 28, 13
74. Todos os direitos reservados a Alexandre de Castro Alves / All Content and Rights Reserved (2012)
Bundle lifecycle
✤ Installation:
✤ Resolves the export and
import package contracts
✤ Activation:
✤ Register the OSGi services
during invocation of
BundleActivator.start()
callback
Frameworks Life Cycle Layer
Figure 4.3 State diagram Framework
4.2.4 Initializing the Framework
Before the framework can be used, it must be initialized. Initialization is caused by the in
implicitly the start method. An initialized framework is operational, but none of its bun
active. This is reflected in the STARTING state. As long as the framework is in this state,
INSTALLED
STARTING
STOPPING
ACTIVE
init
newFramework
RESOLVED
update
init, start
stop
update
stop start
stop
init
start
stop
update
updatestart
init
start
stop
update
init
Wednesday, August 28, 13
75. All Content and Rights Reserved (2013)
Helloworld revisited...
Bundle ID: 70
g! felix:start 70
g! 11:06:54 PM PST: Hello...
And the problem is still there. But in this case, if you refresh the helloworld.client
bundle, which is something you won’t like to do, you’ll get the right message.
The issue is that the PrinterImpl class is located in the same bundle as the
Printer service interface. When you uninstall the PrinterImpl class, you’re also unin-
stalling the Printer class, which is used in the contract with the helloworld.client
bundle. Because the packages can’t be changed without refreshing the bundle, what
happens is that the OSGi framework keeps around an old version of the helloworld
bundle associated with the helloworld.client bundle and will only pick up the new
version of helloworld when the packages are resolved again. This behavior is vendor
specific, which makes it an even bigger problem.
What you need to do to avoid all the confusion is to move the PrinterImpl class to
another bundle separate from the bundle that includes the service interface. You do
this by creating a third bundle named helloworld.impl_1.4.0.jar, which includes the
PrinterImpl and PrinterActivator classes, as shown in figure 2.10.
Printer
helloworld_1.4.0 helloworld.client_1.1.0
PrinterClientActivator
RunnablePrinterClient
helloworld.impl_1.4.0
PrinterActivator
PrinterImpl
Figure 2.10 Bundle helloworld version 1.4 includes the Printer class. Bundle
helloworld.impl version 1.4 includes the PrinterActivator and PrinterImpl classes.
Bundle helloworld.client version 1.1 includes the PrinterClientActivator and
✤ Bundles:
✤ API: helloworld
✤ Implementation: helloworld.impl
✤ Client: helloworld.client
Wednesday, August 28, 13
76. Todos os direitos reservados a Alexandre de Castro Alves / All Content and Rights Reserved (2012)
BundleActivator42 CHAPTER 2 An OSGi framework primer
package manning.osgi.helloworld.impl;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import manning.osgi.helloworld.Printer;
public class PrinterActivator implements BundleActivator {
private ServiceRegistration serviceRegistration;
public void start(BundleContext bundleContext) throws Exception {
serviceRegistration =
bundleContext.registerService(
Printer.class.getName(),
new PrinterImpl(),
null);
}
public void stop(BundleContext bundleContext) throws Exception {
serviceRegistration.unregister();
}
}
You can archive the Printer interface, the Printer implementation, and the
PrinterActivator classes into version 1.4.0 of the helloworld bundle:
Listing 2.7 Registering the Printer service in the OSGi service registry
Printer service
interface
b
Printer service
implementationc
Unregister
serviced
Wednesday, August 28, 13
77. Todos os direitos reservados a Alexandre de Castro Alves / All Content and Rights Reserved (2012)
BundleActivator
42 CHAPTER 2 An OSGi framework primer
package manning.osgi.helloworld.impl;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import manning.osgi.helloworld.Printer;
public class PrinterActivator implements BundleActivator {
private ServiceRegistration serviceRegistration;
public void start(BundleContext bundleContext) throws Exception {
serviceRegistration =
bundleContext.registerService(
Printer.class.getName(),
new PrinterImpl(),
null);
}
public void stop(BundleContext bundleContext) throws Exception {
serviceRegistration.unregister();
}
}
You can archive the Printer interface, the Printer implementation, and the
PrinterActivator classes into version 1.4.0 of the helloworld bundle:
Manifest-Version: 1.0
Listing 2.7 Registering the Printer service in the OSGi service registry
Printer service
interface
b
Printer service
implementationc
Unregister
serviced
51Services and loose coupling
The bundle helloworld.impl needs to import the package manning.osgi.
helloworld, but it doesn’t need to export any packages. The MANIFEST.MF file for
helloworld.impl_1.4.0.jar is shown here:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: helloworld.impl
Bundle-Version: 1.4
Import-Package: manning.osgi.helloworld;version=1.4.0,org.osgi.framework
Bundle-Activator: manning.osgi.helloworld.impl.PrinterActivator
In the helloworld_1.4.0.jar bundle, we keep only the Printer class, and we no longer
need to import the org.osgi.framework package:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: helloworld
Bundle-Version: 1.4
Export-Package: manning.osgi.helloworld;version=1.4.0
Let’s retest:
g! felix:lb
START LEVEL 1
ID|State |Level|Name
0|Active | 0|System Bundle (3.0.6)
1|Active | 1|Apache Felix Bundle Repository (1.6.2)
2|Active | 1|Apache Felix Gogo Command (0.6.1)
3|Active | 1|Apache Felix Gogo Runtime (0.6.1)
4|Active | 1|Apache Felix Gogo Shell (0.6.1)
g! felix:install file:dist/helloworld_1.4.0.jar
Bundle ID: 63
g! felix:start 63
g! felix:install file:dist/helloworld.impl_1.4.0.jarWednesday, August 28, 13
78. Todos os direitos reservados a Alexandre de Castro Alves / All Content and Rights Reserved (2012)
BundleActivator
42 CHAPTER 2 An OSGi framework primer
package manning.osgi.helloworld.impl;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import manning.osgi.helloworld.Printer;
public class PrinterActivator implements BundleActivator {
private ServiceRegistration serviceRegistration;
public void start(BundleContext bundleContext) throws Exception {
serviceRegistration =
bundleContext.registerService(
Printer.class.getName(),
new PrinterImpl(),
null);
}
public void stop(BundleContext bundleContext) throws Exception {
serviceRegistration.unregister();
}
}
You can archive the Printer interface, the Printer implementation, and the
PrinterActivator classes into version 1.4.0 of the helloworld bundle:
Manifest-Version: 1.0
Listing 2.7 Registering the Printer service in the OSGi service registry
Printer service
interface
b
Printer service
implementationc
Unregister
serviced
51Services and loose coupling
The bundle helloworld.impl needs to import the package manning.osgi.
helloworld, but it doesn’t need to export any packages. The MANIFEST.MF file for
helloworld.impl_1.4.0.jar is shown here:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: helloworld.impl
Bundle-Version: 1.4
Import-Package: manning.osgi.helloworld;version=1.4.0,org.osgi.framework
Bundle-Activator: manning.osgi.helloworld.impl.PrinterActivator
In the helloworld_1.4.0.jar bundle, we keep only the Printer class, and we no longer
need to import the org.osgi.framework package:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: helloworld
Bundle-Version: 1.4
Export-Package: manning.osgi.helloworld;version=1.4.0
Let’s retest:
g! felix:lb
START LEVEL 1
ID|State |Level|Name
0|Active | 0|System Bundle (3.0.6)
1|Active | 1|Apache Felix Bundle Repository (1.6.2)
2|Active | 1|Apache Felix Gogo Command (0.6.1)
3|Active | 1|Apache Felix Gogo Runtime (0.6.1)
4|Active | 1|Apache Felix Gogo Shell (0.6.1)
g! felix:install file:dist/helloworld_1.4.0.jar
Bundle ID: 63
g! felix:start 63
g! felix:install file:dist/helloworld.impl_1.4.0.jarWednesday, August 28, 13
79. Todos os direitos reservados a Alexandre de Castro Alves / All Content and Rights Reserved (2012)
BundleActivator
42 CHAPTER 2 An OSGi framework primer
package manning.osgi.helloworld.impl;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import manning.osgi.helloworld.Printer;
public class PrinterActivator implements BundleActivator {
private ServiceRegistration serviceRegistration;
public void start(BundleContext bundleContext) throws Exception {
serviceRegistration =
bundleContext.registerService(
Printer.class.getName(),
new PrinterImpl(),
null);
}
public void stop(BundleContext bundleContext) throws Exception {
serviceRegistration.unregister();
}
}
You can archive the Printer interface, the Printer implementation, and the
PrinterActivator classes into version 1.4.0 of the helloworld bundle:
Manifest-Version: 1.0
Listing 2.7 Registering the Printer service in the OSGi service registry
Printer service
interface
b
Printer service
implementationc
Unregister
serviced
51Services and loose coupling
The bundle helloworld.impl needs to import the package manning.osgi.
helloworld, but it doesn’t need to export any packages. The MANIFEST.MF file for
helloworld.impl_1.4.0.jar is shown here:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: helloworld.impl
Bundle-Version: 1.4
Import-Package: manning.osgi.helloworld;version=1.4.0,org.osgi.framework
Bundle-Activator: manning.osgi.helloworld.impl.PrinterActivator
In the helloworld_1.4.0.jar bundle, we keep only the Printer class, and we no longer
need to import the org.osgi.framework package:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: helloworld
Bundle-Version: 1.4
Export-Package: manning.osgi.helloworld;version=1.4.0
Let’s retest:
g! felix:lb
START LEVEL 1
ID|State |Level|Name
0|Active | 0|System Bundle (3.0.6)
1|Active | 1|Apache Felix Bundle Repository (1.6.2)
2|Active | 1|Apache Felix Gogo Command (0.6.1)
3|Active | 1|Apache Felix Gogo Runtime (0.6.1)
4|Active | 1|Apache Felix Gogo Shell (0.6.1)
g! felix:install file:dist/helloworld_1.4.0.jar
Bundle ID: 63
g! felix:start 63
g! felix:install file:dist/helloworld.impl_1.4.0.jarWednesday, August 28, 13
80. All Content and Rights Reserved (2013)
Simplifying the programming
model
42 CHAPTER 2 An OSGi framework primer
package manning.osgi.helloworld.impl;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import manning.osgi.helloworld.Printer;
public class PrinterActivator implements BundleActivator {
private ServiceRegistration serviceRegistration;
public void start(BundleContext bundleContext) throws Exception {
serviceRegistration =
bundleContext.registerService(
Printer.class.getName(),
new PrinterImpl(),
null);
}
public void stop(BundleContext bundleContext) throws Exception {
serviceRegistration.unregister();
}
}
You can archive the Printer interface, the Printer implementation, and the
PrinterActivator classes into version 1.4.0 of the helloworld bundle:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Listing 2.7 Registering the Printer service in the OSGi service registry
Printer service
interface
b
Printer service
implementationc
Unregister
serviced
Wednesday, August 28, 13
81. All Content and Rights Reserved (2013)
Simplifying the programming
model
Wednesday, August 28, 13
82. All Content and Rights Reserved (2013)
Simplifying the programming
model
CHAPTER 2 An OSGi framework primer
package manning.osgi.helloworld.impl;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import manning.osgi.helloworld.Printer;
public class PrinterActivator implements BundleActivator {
private ServiceRegistration serviceRegistration;
public void start(BundleContext bundleContext) throws Exception {
serviceRegistration =
bundleContext.registerService(
Printer.class.getName(),
new PrinterImpl(),
null);
}
public void stop(BundleContext bundleContext) throws Exception {
serviceRegistration.unregister();
}
}
You can archive the Printer interface, the Printer implementation, and the
PrinterActivator classes into version 1.4.0 of the helloworld bundle:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: helloworld
Bundle-Version: 1.4
Export-Package: manning.osgi.helloworld;version=1.4.0
Import-Package: org.osgi.framework
Bundle-Activator: manning.osgi.helloworld.impl.PrinterActivator
In the start method, you instantiate the service by specifying its interface B and
implementation c, and you register it in the service registry using the bundle-
Context.registerService() method. This method returns a serviceRegistration
object, which represents the registered service.
Listing 2.7 Registering the Printer service in the OSGi service registry
Printer service
interface
b
Printer service
implementationc
Unregister
serviced
Wednesday, August 28, 13
83. All Content and Rights Reserved (2013)
Simplifying the programming
model
<blueprint xmlns="http://www.osgi.org/xmlns/
blueprint/v1.0.0">
<bean id="impl"
class="manning.osgi.helloworld.impl.PrinterImpl" />
<service
interface="manning.osgi.helloworld.Printer"
ref="impl" />
</blueprint>
CHAPTER 2 An OSGi framework primer
package manning.osgi.helloworld.impl;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import manning.osgi.helloworld.Printer;
public class PrinterActivator implements BundleActivator {
private ServiceRegistration serviceRegistration;
public void start(BundleContext bundleContext) throws Exception {
serviceRegistration =
bundleContext.registerService(
Printer.class.getName(),
new PrinterImpl(),
null);
}
public void stop(BundleContext bundleContext) throws Exception {
serviceRegistration.unregister();
}
}
You can archive the Printer interface, the Printer implementation, and the
PrinterActivator classes into version 1.4.0 of the helloworld bundle:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: helloworld
Bundle-Version: 1.4
Export-Package: manning.osgi.helloworld;version=1.4.0
Import-Package: org.osgi.framework
Bundle-Activator: manning.osgi.helloworld.impl.PrinterActivator
In the start method, you instantiate the service by specifying its interface B and
implementation c, and you register it in the service registry using the bundle-
Context.registerService() method. This method returns a serviceRegistration
object, which represents the registered service.
Listing 2.7 Registering the Printer service in the OSGi service registry
Printer service
interface
b
Printer service
implementationc
Unregister
serviced
Wednesday, August 28, 13
84. All Content and Rights Reserved (2013)
Blueprint (Spring dm)
✤ Bundle client (helloworld.client)
✤ META-INF/spring/blueprint.xml
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<reference id="printer" interface="manning.osgi.helloworld.Printer" />
<bean id="client" class="manning.osgi.helloworld.PrinterClient" >
<property name="printerService" ref="printer" />
</bean>
</blueprint>
Wednesday, August 28, 13
85. All Content and Rights Reserved (2013)
Blueprint (Spring dm)
✤ Bundle client (helloworld.client)
✤ META-INF/spring/blueprint.xml
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<reference id="printer" interface="manning.osgi.helloworld.Printer" />
<bean id="client" class="manning.osgi.helloworld.PrinterClient" >
<property name="printerService" ref="printer" />
</bean>
</blueprint>
Specification of the
application components
Wednesday, August 28, 13
86. All Content and Rights Reserved (2013)
Vertical Solutions
✤ OSGi allows the creation of layered frameworks:
✤ Spring-dm
✤ Service integration
✤ Creation of new programming models
Wednesday, August 28, 13
87. All Content and Rights Reserved (2013)
Simplifying the
FingerprintService
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<fingerprint id="fingerprint" type="MD4" />
<bean id="client" class="manning.osgi.FingerprintClient" />
</blueprint>
public class FingerprintClient {
public void setHash(byte [] hash)
{
//
}
}
Infrastructure automatically calls
setHash() using toString() in the client
instance.
client.setHash(
fingerprint.hash(client.toString()))
Wednesday, August 28, 13
88. All Content and Rights Reserved (2013)
Simplifying the
FingerprintService
✤ Customer only has to create JAR (bundle) with:
✤ FingerprintClient class
✤ blueprint.xml
✤ MANIFEST.MF with OSGi header entries
✤ Bundle-SymbolicName: fingerprintClient
✤ In this case, it is not necessary for the customer to import a particular
package or to make use of a particular service.
public class FingerprintClient {
public void setHash(byte [] hash)
{
//
}
}
Wednesday, August 28, 13
89. All Content and Rights Reserved (2013)
OtherVertical Bundles
idea of containers and application bundles.
13.1 Application bundles and their containers
As you’ve seen in the previous chapters, a common pattern for enabling a bundle with
a new feature is to annotate the bundle’s manifest file. For example, to enable a bun-
dle to persist its Java classes, you can add the Meta-Persistence header entry to its
MANIFEST.MF file. The following table summarizes some of the standard manifest
header entries used to create feature-specific powered bundles, or, perhaps a bit more col-
orful, bundle flavors.
Table 13.1 Flavored bundles
Name Description Manifest header
WAB Web application bundle Web-ContextPath
Persistence bundle Bundle with persistence units Meta-Persistence
SCA config bundle Bundle with SCA configuration SCA-Configuration
Component bundle Bundle with declarative components Service-Component
Blueprint bundle Bundle with Blueprint components Bundle-Blueprint
Endpoint bundle Bundle with endpoint descriptions Remote-Service
Application bundles
Table 13.1 lists just a few examples of the different flavors of bundles that exist. Some
of them have been discussed in previous chapters, but some of them are out of theWednesday, August 28, 13
90. All Content and Rights Reserved (2013)
Vertical Servers: Oracle Event
Processing
✤ Started as a vertical server for processing events for financial markets
✤ Defines its own programming model for event processing
Wednesday, August 28, 13
91. All Content and Rights Reserved (2013)
Vertical Servers: Oracle Event
Processing
Wednesday, August 28, 13
92. All Content and Rights Reserved (2013)
Conclusion
✤ OSGi helps in the development of systems that are:
✤ modular
✤ bundles
✤ extensible
✤ services
✤ Modular and extensible systems allows one to create their own
vertical infrastructure or framework
Wednesday, August 28, 13
93. All Content and Rights Reserved (2013)
In the trenches with OEP
✤ Use tooling, especially PMD
✤ Introspects Java classes and generates proper MANIFEST header
entries for imports and exports
✤ Be careful not to overdue it and simply export and import
everything. Know what you are doing when using wildcards
Wednesday, August 28, 13
94. All Content and Rights Reserved (2013)
In the trenches with OEP
✤ Do Semantic Versioning (http://www.osgi.org/wiki/uploads/
Links/SemanticVersioning.pdf)
✤ Change minor version for implementation changes
✤ Change major version for interface changes
✤ Import as [X.Y,X+1.0) (for example: [1.2,2.0))
Wednesday, August 28, 13
95. All Content and Rights Reserved (2013)
In the trenches with OEP
✤ All features should have at least two bundles: an interface and an
implementation bundle
✤ Some features may even more, for example, one for management,
one for SPIs, etc.
✤ Also, all features should have a ‘test bundle’ that runs as a Junit
test-case
Wednesday, August 28, 13
96. All Content and Rights Reserved (2013)
In the trenches with OEP
✤ Don’t use statics, instead create singleton services
✤ Don’t use JDK’s service property files, these are just another type of
‘static’
✤ Don’t expect to be able to cheat by using ‘Reflection’
✤ For example, to implement a general purpose configuration
system, we had to pass along the application’s (bundle) class-
loader, otherwise there is infra bundles can’t see application
bundle’s resources
Wednesday, August 28, 13
97. All Content and Rights Reserved (2013)
In the trenches with OEP
✤ Getting the right order of installation and start-up is hard!
✤ Make sure your service registration and retrieval go through
ServiceTracker or some other mechanism that avoids temporal
cohesion
✤ Create layers of features, such as: core, domain-feature, application,
etc.
Wednesday, August 28, 13
98. Todos os direitos reservados a Alexandre de Castro Alves / All Content and Rights Reserved (2012)
Developing Modular
and Extensible
Systems using OSGi
adcalves@gmail.com
alex.alves@oracle.com
http://www.manning.com/alves/
http://adcalves.wordpress.com
http://www.oracle.com/technetwork/middleware/complex-event-
processing/overview/index.html
Wednesday, August 28, 13