Author: marrs
Date: Wed Mar 4 10:39:19 2015
New Revision: 1663924
URL: http://svn.apache.org/r1663924
Log:
First draft of DM4 docs.
Added:
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/annotations.mdtext
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/background.mdtext
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/bundles-and-dependencies.mdtext
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/design-patterns.mdtext
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/development.mdtext
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/history.mdtext
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/migrating-from-earlier-versions.mdtext
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/migrating-from-other-solutions.mdtext
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/performance-tuning.mdtext
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/resources.mdtext
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/reference/
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/reference/component-adapter.mdtext
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/reference/component-aspect.mdtext
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/reference/component-resource-adapter.mdtext
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/reference/component-singleton.mdtext
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/reference/components.mdtext
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/reference/dependencies.mdtext
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/reference/dependency-bundle.mdtext
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/reference/dependency-configuration.mdtext
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/reference/dependency-resource.mdtext
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/reference/dependency-service.mdtext
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/reference/external-links.mdtext
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/tutorials/
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/tutorials/getting-started.mdtext
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/tutorials/leveraging-the-shell.mdtext
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/tutorials/working-with-annotations.mdtext
Modified:
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4.mdtext
Modified:
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4.mdtext
URL:
http://svn.apache.org/viewvc/felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4.mdtext?rev=1663924&r1=1663923&r2=1663924&view=diff
==============================================================================
---
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4.mdtext
(original)
+++
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4.mdtext
Wed Mar 4 10:39:19 2015
@@ -1,3 +1,52 @@
Title: Apache Felix Dependency Manager 4
-## Placeholder
+## Introduction
+
+In a service oriented architecture, applications are built out of components
that are packaged in bundles and interact through services. These components,
that both publish services and depend on other services, form networks that are
often dynamic in nature. That makes managing these dependencies something the
developer needs to address.
+
+Whilst the OSGi framework provides the low-level building blocks to do that in
the form of service listeners and trackers, these should not be used directly
by developers. Instead, a more declarative approach works best, and the
Dependency Manager provides this in the form of a declarative API and/or
annotations that allow you to dynamically declare and change dependencies.
+
+On top of that, a set of OSGi design patterns are defined and supported that
can be used as building blocks for more complex applications.
+
+The documentation for the dependency manager is split into three sections:
+
+1. Step-by-step tutorials which provide a good introduction to the technology
and should get you started quickly.
+2. Overviews and guides that provide more in-depth knowledge about specific
aspects of the dependency manager.
+3. Reference materials that describe all the individual nuts and bolts.
+
+Below is the full table of contents.
+
+## Table of Contents
+
+### Step-by-step Tutorials
+
+* [Getting
started](apache-felix-dependency-manager-4/tutorials/getting-started.html)
+* [Working with
annotations](apache-felix-dependency-manager-4/tutorials/working-with-annotation.html)
+* [Leveraging the
shell](apache-felix-dependency-manager-4/tutorials/leveraging-the-shell.html)
+
+### Overviews and Guides
+
+* [History](apache-felix-dependency-manager-4/guides/history.html)
+* [Background](apache-felix-dependency-manager-4/guides/background.html)
+* [Bundles and
dependencies](apache-felix-dependency-manager-4/guides/bundles-and-dependencies.html)
+* [Migrating from earlier
versions](apache-felix-dependency-manager-4/guides/migrating-from-earlier-versions.html)
+* [Migrating from other
solutions](apache-felix-dependency-manager-4/guides/migrating-from-other-solutions.html)
+* [Annotations](apache-felix-dependency-manager-4/guides/annotations.html)
+* [Performance
Tuning](apache-felix-dependency-manager-4/guides/performance-tuning.html)
thread pools, indices, ...
+* [Development](apache-felix-dependency-manager-4/guides/development.html)
setting up, adding dependencies, shell commands?
+* [Design
Patterns](apache-felix-dependency-manager-4/guides/design-patterns.html)
+* [Resources](apache-felix-dependency-manager-4/guides/resources.html)
+
+### Reference Guide
+
+* [Components](apache-felix-dependency-manager-4/reference/components.html)
+ *
[Singleton](apache-felix-dependency-manager-4/reference/component-singleton.html)
+ * [Aspect](apache-felix-dependency-manager-4/reference/component-aspect.html)
+ *
[Adapter](apache-felix-dependency-manager-4/reference/component-adapter.html)
+ * [Resource
Adapter](apache-felix-dependency-manager-4/reference/component-resource-adapter.html)
+* [Dependencies](apache-felix-dependency-manager-4/reference/dependencies.html)
+ *
[Service](apache-felix-dependency-manager-4/reference/dependency-service.html)
+ *
[Configuration](apache-felix-dependency-manager-4/reference/dependency-configuration.html)
+ * [Bundle](apache-felix-dependency-manager-4/reference/dependency-bundle.html)
+ *
[Resource](apache-felix-dependency-manager-4/reference/dependency-resource.html)
+* [External Links and
Articles](apache-felix-dependency-manager-4/reference/external-links.html)
Added:
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/annotations.mdtext
URL:
http://svn.apache.org/viewvc/felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/annotations.mdtext?rev=1663924&view=auto
==============================================================================
---
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/annotations.mdtext
(added)
+++
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/annotations.mdtext
Wed Mar 4 10:39:19 2015
@@ -0,0 +1,352 @@
+Title: Dependency Manager SpellChecker Sample
+Excerpt: Basic concepts using a full SpellChecker sample code.
+
+This section presents a quick overview of the capabilities and usage of the
+DependencyManager java 5 annotations. In particular, we will recap the
DependencyManager
+annotation architecture, and identify some simple usage scenarios using a
SpellChecker
+sample application with annotated components.
+The application is available from the felix trunk, in the
dependencymanager/samples.annotation
+subproject.
+
+## Architecture
+
+Instead of writing Activators which extends the DependencyActivatorBase class,
service
+components can now be annotated using the annotations provided by the
+*org.apache.felix.dependencymanager.annotation* bundle. Annotations are not
reflectively
+parsed at runtime; but we use a BND plugin which scans annotations at
compilation phase
+and generates a compact metadata file in the bundle's
META-INF/dependencymanager
+subdirectory. This has the following benefits:
+
+- JVM startup speed is not affected, and class files are not parsed when the
framework is starting
+- Moreover, since the annotations are not retained by the VM at runtime, it is
not necessary to load the annotation API bundle at runtime.
+
+At runtime, the metadata generated during the compilation phase are processed
by a
+specific DependencyManager Runtime bundle, which is in charge of managing the
service
+component lifecycle and dependencies. This Runtime bundle actually uses the
+DependencyManager programmatic API in order to manage the annotated
components.
+Annotated components can then be inspected with the DependencyManager Gogo
shell, as it is
+the case with DM components declared through the programmatic DM API.
+
+## Registering a Service
+
+To register a service, your can annotate your class with a *@Component*
annotation, and
+an instance of your class will be registered under all directly implemented
interfaces
+into the OSGi registry. You can however take control on the interfaces to be
exposed, and
+in this case, you can use the *provides* attribute, which takes a list of
classes to
+expose from the registry.
+
+To illustrate this, we are now introducing a SpellChecker application which
provides a
+Felix "spellcheck" Gogo shell command. Gogo is the new shell supported by the
Felix
+Framework. Our "spellcheck" command is implemented by the SpellChecker
component which
+accepts a string as parameter. This string is then checked for proper
existence. To do
+the checking, The SpellChecker class has a required/multiple (1..N)
dependency over
+every available DictionaryService services. Such DictionaryService represents
a real
+dictionary for a given language (it has a *lang* service property), and is
+configurable/instantiable from the OSGi Configuration Admin Service.
+
+Configuration Admin service provides a mechanism for configuring components
+(using ManagedService interfaces), and WebConsole actually implements this
service.
+ConfigAdmin is also able to instantiate some Services (using
ManagedServiceFactory
+interfaces).
+
+Now we have introduced the background, here is the SpellCheck component:
+
+ :::java
+ @Component(provides={SpellChecker.class},
+ properties={@Property(name=CommandProcessor.COMMAND_SCOPE,
value="dmsample.annotation"),
+ @Property(name=CommandProcessor.COMMAND_FUNCTION,
values={"spellcheck"})})
+ public class SpellChecker {
+ // --- Gogo Shell command
+
+ @Descriptor("checks if word is found from an available dictionary")
+ public void spellcheck(@Descriptor("the word to check")String word) {
+ // Check the proper existence of the word parameter, using injected
DictionaryService instances
+ // ...
+ }
+ }
+
+
+In the code above, you see that the SpellCheck is annotated with the
*@Component*
+annotation. Gogo runtime does not required shell commands to implement a
specific
+interface. Commands just have to register some Pojos in the OSGi registry,
but the only
+thing required is to provide the Pojos with two service properties (
COMMAND_SCOPE, and
+COMMAND_FUNCTION) which will be used by the Gogo runtime when instropecting
the Pojo
+for invoking the proper functions.
+
+
+So, coming back to the sample code, the SpellChecker class registers itself
into the OSGi registry, using the *provides* attribute, which just refer to our
SpellChecker class, and the two mandatory Gogo service properties are also
specified using the *@Property* annotation. It is not shown here, but service
properties can also be provided dynamically from a method that can return a
Map, and annotated with the *@Start* lifecycle callback, but we will see this
feature in a another section.
+
+## Depending on a Service
+
+Our SpellChecker component can expose itself as a Gogo shell command, but
before being
+registered into the OSGi registry, we also need to be injected with two
dependencies:
+one required dependency (at minimum) on a DictionaryService, and another
optional one on
+a LogService. First, let's look at the DictionaryService, which is a simple
interface:
+
+ :::java
+ public interface DictionaryService {
+ /**
+ * Check for the existence of a word.
+ * @param word the word to be checked.
+ * @return true if the word is in the dictionary, false otherwise.
+ */
+ public boolean checkWord(String word);
+ }
+
+And here is our previous SpellChecker component, augmented with two new
ServiceDependency
+annotations:
+
+ :::java
+ @Component(provides={SpellChecker.class},
+ properties={@Property(name=CommandProcessor.COMMAND_SCOPE,
value="dmsample.annotation"),
+ @Property(name=CommandProcessor.COMMAND_FUNCTION,
values={"spellcheck"})})
+ public class SpellChecker {
+ @ServiceDependency(required = false)
+ private LogService m_log;
+
+ private CopyOnWriteArrayList<DictionaryService> m_dictionaries = new
CopyOnWriteArrayList<DictionaryService>();
+
+ @ServiceDependency(removed = "removeDictionary")
+ protected void addDictionary(DictionaryService dictionary) {
+ m_dictionaries.add(dictionary);
+ }
+
+ protected void removeDictionary(DictionaryService dictionary) {
+ m_dictionaries.remove(dictionary);
+ }
+
+ // --- Gogo Shell command
+
+ @Descriptor("checks if word is found from an available dictionary")
+ public void spellcheck(@Descriptor("the word to check")String word) {
+ m_log.log(LogService.LOG_INFO, "Checking spelling of word \"" + word
+ + "\" using the following dictionaries: " + m_dictionaries);
+
+ for (DictionaryService dictionary : m_dictionaries) {
+ if (dictionary.checkWord(word)) {
+ System.out.println("word " + word + " is correct");
+ return;
+ }
+ }
+ System.err.println("word " + word + " is incorrect");
+ }
+ }
+
+There are many things to describe in the code above:
+
+First, we define an optional dependency on the LogService, by defining a
+*@ServiceDependency(required=false)* annotation on our m_logService field: This
+means that our component will be provided into the OSGi registry even if there
+is no available LogService, and in this case, a NullObject will be injected in
+our class field;
+This will avoid to check for nullability, when using the m_logService field.
+All optional dependencies applied on class fields are injected with a
+NullObject (when not available).
+The NullObject can be invoked and will do nothing. For a lot of cases that is
+good enough to handle optional dependencies. But when you really want to check
+if an optional service is there or not, then you have to apply the optional
+dependency on a callback method, which will be called when the optional
+service is available.
+
+Next comes the dependency on the DictionaryService. Here, we use a
*ServiceDependency*
+annotation, but this time we apply it on a method (*add/removeDictionary*).
There is no
+need to specify the "*required=true*" flag because it is the default value.
Notice that
+this behavior is different from the API, where service dependencies are
optional by default
+. We use a callback method, because we just need to register all available
+DictionaryService services in our dictionary list, which is used when checking
word
+existence. This list is a copy on write list because the dependency may be
injected at
+any time, possibly from another thread. So, using a copy on write list avoid
us to use synchronized methods.
+
+## Creating a Service from ConfigAdmin
+
+The *@Component* annotation is not the only one for creating services. Another
one is
+the *@FactoryConfigurationAdapterService* annotation which allows to
instantiate many
+instances of the same annotated service class from ConfigAdmin (and
WebConsole).
+To illustrate this, let's take a look at our DictionaryImpl class which is
part of the
+SpellChecker sample. This service is required by the SpellChecker component,
when
+checking for proper word existence. And you can instantiate as many
DictionaryService as
+you want, from ConfigAdmin ...
+
+ :::java
+ @FactoryConfigurationAdapterService(factoryPid="DictionaryImplFactoryPid",
updated="updated")
+ public class DictionaryImpl implements DictionaryService {
+ /**
+ * We store all configured words in a thread-safe data structure,
because ConfigAdmin
+ * may invoke our updated method at any time.
+ */
+ private CopyOnWriteArrayList<String> m_words = new
CopyOnWriteArrayList<String>();
+
+ /**
+ * Our Dictionary language.
+ */
+ private String m_lang;
+
+ /**
+ * Our service will be initialized from ConfigAdmin, and we also handle
updates in this method.
+ * @param config The configuration where we'll lookup our words list
(key="words").
+ */
+ protected void updated(Dictionary<String, ?> config) {
+ m_lang = (String) config.get("lang");
+ m_words.clear();
+ String[] words = (String[]) config.get("words");
+ for (String word : words) {
+ m_words.add(word);
+ }
+ }
+
+ /**
+ * Check if a word exists if the list of words we have been configured
from ConfigAdmin/WebConsole.
+ */
+ public boolean checkWord(String word) {
+ return m_words.contains(word);
+ }
+ }
+
+Our DictionaryImpl class implements a DictionaryService, and our class will be
registered
+under that interface (all directly implemented interfaces are used when
registering the
+service, but you can select some others using the *provides* attribute).
+The *@FactoryConfigurationAdapterService* annotation will instantiate our
service for
+each configuration created from web console (and matching our
"DictionaryImplFactoryPid"
+factoryPid).
+
+We also use the *updated* attribute, which specifies a callback method which
will handle
+properties configured by ConfigAdmin. The updated callback will also be
called when our
+properties are changing. Every properties are propagated to our service
properties,
+unless the properties starting with a dot ("."). Configuration properties
starting with
+a dot (".") are considered private and are not propagated.
+
+Notice that this annotation also supports optional meta type attributes, which
allow to
+customize the ConfigAdmin GUI, with custom messages, like heading/property
title,
+property type, property description, etc ...). So, let's revisit our
DisctionaryImpl
+service, but this time with meta type support:
+
+ :::java
+ @FactoryConfigurationAdapterService(factoryPid="DictionaryImplFactoryPid",
+ propagate=true,
+ updated="updated",
+ heading="Dictionary Services",
+ description="Declare here some Dictionary instances, allowing to
instantiates some DictionaryService services for a given dictionary language",
+ metadata={
+ @PropertyMetaData(
+ heading="Dictionary Language",
+ description="Declare here the language supported by this
dictionary. " +
+ "This property will be propagated with the Dictionary
Service properties.",
+ defaults={"en"},
+ id="lang",
+ cardinality=0),
+ @PropertyMetaData(
+ heading="Dictionary words",
+ description="Declare here the list of words supported by this
dictionary.",
+ defaults={"hello", "world"},
+ id="words",
+ cardinality=Integer.MAX_VALUE)
+ }
+ )
+ public class DictionaryImpl implements DictionaryService {
+ ... code same as before
+ }
+
+
+## Providing an Aspect
+
+As we have seen in the previous section, there are many annotations that can
be used
+to specify a service. Another one is the *@AspectService* annotation. This
annotation
+allows to *decorate* an existing service in order to add certain
"capabilities" to it,
+like adding a specific caching mechanism to a storage service or
implementing logging.
+Aspects can be plugged to an existing service at runtime, and can also be
removed
+dynamically. This is transparent, and the clients using the existing service
are not
+interrupted, they are just rebound with the aspect service.
+
+As an example, we go back to our SpellChecker application, and we are now
looking at the
+DictionaryAspect class. This class uses the *@Aspect* Service annotation in
+order to add some custom words to an English DictionaryService (with the
+service property lang=en).
+The Extra words to add to the English Dictionary will be configured from
+ConfigAdmin. That's why the class also uses a *@ConfigurationDependency*
annotation:
+
+ :::java
+ @AspectService(ranking = 10, filter = "(lang=en)")
+ public class DictionaryAspect implements DictionaryService {
+ /**
+ * This is the service this aspect is applying to.
+ */
+ private volatile DictionaryService m_originalDictionary;
+
+ /**
+ * We store all configured words in a thread-safe data structure,
because ConfigAdmin may
+ * invoke our updated method at any time.
+ */
+ private CopyOnWriteArrayList<String> m_words = new
CopyOnWriteArrayList<String>();
+
+ /**
+ * Defines a configuration dependency for retrieving our english custom
words (by default,
+ * our PID is our full class name).
+ */
+ @ConfigurationDependency
+ protected void updated(Dictionary<String, ?> config) {
+ m_words.clear();
+ String[] words = (String[]) config.get("words");
+ for (String word : words) {
+ m_words.add(word);
+ }
+ }
+
+ /**
+ * Checks if a word is found from our custom word list. if not,
delegate to the decorated
+ * dictionary.
+ */
+ public boolean checkWord(String word) {
+ if (m_words.contains(word)) {
+ return true;
+ }
+ return m_originalDictionary.checkWord(word);
+ }
+ }
+
+The annotation does the following: because our class implements the
DictionaryService
+contract, it will instantiate our service each time it finds another existing
+DictionaryService matching the filter attribute we provide in the annotation
+(filter="(lang=en)"). And it will inject the existing service in our
+m_originalDictionary field, by reflection. But we can also specify a field
attribute in
+the annotation, if we want to explicitly inject the existing service in a
given class
+field. So, any client depending on an English DictionaryService will be
transparently
+rebound to our aspect Dictionary.
+
+In the Annotation, also notice the *ranking* attribute: It is the level used
to organize
+the aspect chain ordering (multiple aspects may be applied on a given
service).
+
+
+The *ConfigurationDependency* is another dependency that we have not seen
before: it is
+used to configure the extra English words from ConfigAdmin. This annotation
normally
+requires a pid parameter, which is a persistent identifier uniquely
identifying our
+component, but by default, the pid is set to the fully qualified name of our
class.
+
+Notice that like the *@FactoryConfigurationAdapterService*, the
*@ConfigurationDependency*
+annotation also supports meta type attributes.
+
+## How to run the sample code
+
+Install the following bundles:
+
+ org.apache.felix.configadmin
+ org.apache.felix.metatype
+ org.apache.felix.http.jetty
+ org.apache.felix.webconsole
+
+ org.apache.felix.dependencymanager
+ org.apache.felix.dependencymanager.shell
+ org.apache.felix.dependencymanager.runtime
+ org.apache.felix.dependencymanager.samples.annotation
+
+Start felix.
+
+Go to web console: in the Configuration panel, edit the "Dictionary Services"
Configuration. By default, an English dictionary is displayed. Just
click on "save", then refresh your web browser (click on refresh): you will
see a new dictionary service instance. At this point, a DictionaryService
service will be enabled (with the service property "lang=en"), and the
SpellCheck component will be injected with it. Then you should see the
"spellcheck" command, when typing "help" on the gogo shell.
+
+Just type "spellcheck hello", and the command should reply a fantastic
message, like "word hello is correct".
+
+You can also click on the "Aspect Dictionary" button, in order to decorate the
+English dictionary with some custom words. By default, the "aspect" word is
+pre configured, but you can click on the "+" button in order to add more
words.
+Then click on Save. At this point, the English DictionaryService will be
decorated with
+the aspect service. So, now, if you type "spellcheck aspect", then the
message
+"word aspect is correct" should be displayed.
Added:
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/background.mdtext
URL:
http://svn.apache.org/viewvc/felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/background.mdtext?rev=1663924&view=auto
==============================================================================
---
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/background.mdtext
(added)
+++
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/background.mdtext
Wed Mar 4 10:39:19 2015
@@ -0,0 +1,28 @@
+Title: Apache Felix Dependency Manager - Background
+
+## Background
+
+In an OSGi framework, services are deployed using bundles and these bundles
feature two types of dependencies:
+
+1. Package dependencies. A bundle can export a package which others import.
These dependencies, although dynamic, are relatively easy to handle and the
whole resolution process is handled by the OSGi framework for you.
+1. Service dependencies. Services, implemented by components inside of
bundles, can have their own life cycle within that of their containing bundle
and therefore can be registered and unregistered at any time. Other components
often depend on these services and need to deal with changes in their
availability.
+
+When you look at dependency management, there are two aspects you need to take
into account:
+
+The first is managing software configurations. This means you need to manage
the dependencies from a configuration standpoint. What you are managing are
bundles, since those are the units of deployment. What you need to manage are
the package and service dependencies between bundles. Package dependencies are
always visible by examining the bundle manifest and when a bundle is installed
the framework will try to resolve such dependencies before that bundle can even
be started. Service dependencies are only optionally described in the manifest
by a list of services a bundle might export as well as a list it might use
(import). The words 'optionally' and 'might' already indicate that these aren't
things we can depend on. Even worse, these keywords have by now been
deprecated. Besides that, the framework doesn't have to perform any checks on
these attributes.
+
+The second is managing service dependencies at runtime. As mentioned before, a
service oriented architecture is dynamic by design, so your implementation
should be able to deal with this. Bundles can start in any order and any
service can go away or be replaced by a different implementation at any point
in time. OSGi itself offers basic assistance for tracking services. You can
track them yourself by registering as a service listener. A slightly more
advanced way is to create a service tracker, which you can subsequently query,
or have it notify you on changes. All of these are too low-level to be good
building blocks for developers.
+
+In real implementations, you are probably going to track multiple services.
Using service trackers in such a scenario has the tendency to result in
dependency logic that is entangled in the implementation instead of being
expressed in a declarative way. Using a declarative way to specify dependencies
has clear advantages when it comes to monitoring and managing them, a task that
becomes more and more important in modern, federated, service oriented
environments.
+
+The Dependency Manager provides you with the right building blocks to
declaratively specify dependencies using a straightforward Java API that is
easy to maintain and refactor.
+
+## Design Goals
+
+The goals that drove the design of the dependency manager are:
+
+* Provide a clean separation between a component implementation and the "glue"
that binds it to the OSGi framework. The component implementation should not
have to contain any OSGi specific code. In other words, it should be a POJO
(Plain Old Java Object).
+* Minimize the amount of code that needs to be written. The specification and
management of dependencies should be automated as much as possible, whilst
still providing enough flexibility to customize the system.
+* Be extensible. Even though the core bundle provides a lot of different
dependencies already, you should be able to add your own types of dependencies
easily.
+* Easy to monitor and debug. Being a dynamic system, it's important to be able
to see what the state of all components and dependencies are at any point in
time.
+* Supporting powerful high level design patterns. When building real-world
applications, more complex patterns need to be used, such as aspects and
adapters. Support for these needs to be built into the core.
Added:
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/bundles-and-dependencies.mdtext
URL:
http://svn.apache.org/viewvc/felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/bundles-and-dependencies.mdtext?rev=1663924&view=auto
==============================================================================
(empty)
Added:
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/design-patterns.mdtext
URL:
http://svn.apache.org/viewvc/felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/design-patterns.mdtext?rev=1663924&view=auto
==============================================================================
(empty)
Added:
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/development.mdtext
URL:
http://svn.apache.org/viewvc/felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/development.mdtext?rev=1663924&view=auto
==============================================================================
(empty)
Added:
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/history.mdtext
URL:
http://svn.apache.org/viewvc/felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/history.mdtext?rev=1663924&view=auto
==============================================================================
---
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/history.mdtext
(added)
+++
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/history.mdtext
Wed Mar 4 10:39:19 2015
@@ -0,0 +1,13 @@
+Title: Apache Felix Dependency Manager - History
+
+## The early years
+
+The first version of the Dependency Manager was created when Marcel started
working on his first commercial OSGi project back in 2002. At that time, the
OSGi specification was still at R2, and the only solution for managing
dependencies was "service binder" which did not support the dynamics we needed
at that time. Therefore, dependency manager was created, based on a fluent,
declarative Java API.
+
+In 2005, after writing a white paper, dependency manager was presented at the
OSGi DevCon in Paris. At that time, the project had been open sourced, but not
yet at Apache. When the Oscar project finally decided to move to the incubator,
where it became Felix, Dependency Manager was one of the subprojects that
joined.
+
+## Life at Apache
+
+The move to Apache definitely gave the project a lot more visibility and,
besides a larger user base, also attracted a few very talented developers.
Xander did a lot of work in getting some of the higher level design patterns
implemented, and Pierre added support for annotations and ensured that the code
ran well on really big, multi-core systems.
+
+In 2014, after many discussions about new features and improvements we would
like to add, we started experimenting with a completely new codebase,
redesigning some aspects from the ground up based on all the knowledge and
experience that we had gained over the years. About a year later, that lead to
the release of Dependency Manager 4.
Added:
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/migrating-from-earlier-versions.mdtext
URL:
http://svn.apache.org/viewvc/felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/migrating-from-earlier-versions.mdtext?rev=1663924&view=auto
==============================================================================
(empty)
Added:
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/migrating-from-other-solutions.mdtext
URL:
http://svn.apache.org/viewvc/felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/migrating-from-other-solutions.mdtext?rev=1663924&view=auto
==============================================================================
(empty)
Added:
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/performance-tuning.mdtext
URL:
http://svn.apache.org/viewvc/felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/performance-tuning.mdtext?rev=1663924&view=auto
==============================================================================
(empty)
Added:
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/resources.mdtext
URL:
http://svn.apache.org/viewvc/felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/guides/resources.mdtext?rev=1663924&view=auto
==============================================================================
(empty)
Added:
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/reference/component-adapter.mdtext
URL:
http://svn.apache.org/viewvc/felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/reference/component-adapter.mdtext?rev=1663924&view=auto
==============================================================================
(empty)
Added:
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/reference/component-aspect.mdtext
URL:
http://svn.apache.org/viewvc/felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/reference/component-aspect.mdtext?rev=1663924&view=auto
==============================================================================
(empty)
Added:
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/reference/component-resource-adapter.mdtext
URL:
http://svn.apache.org/viewvc/felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/reference/component-resource-adapter.mdtext?rev=1663924&view=auto
==============================================================================
(empty)
Added:
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/reference/component-singleton.mdtext
URL:
http://svn.apache.org/viewvc/felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/reference/component-singleton.mdtext?rev=1663924&view=auto
==============================================================================
(empty)
Added:
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/reference/components.mdtext
URL:
http://svn.apache.org/viewvc/felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/reference/components.mdtext?rev=1663924&view=auto
==============================================================================
(empty)
Added:
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/reference/dependencies.mdtext
URL:
http://svn.apache.org/viewvc/felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/reference/dependencies.mdtext?rev=1663924&view=auto
==============================================================================
(empty)
Added:
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/reference/dependency-bundle.mdtext
URL:
http://svn.apache.org/viewvc/felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/reference/dependency-bundle.mdtext?rev=1663924&view=auto
==============================================================================
(empty)
Added:
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/reference/dependency-configuration.mdtext
URL:
http://svn.apache.org/viewvc/felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/reference/dependency-configuration.mdtext?rev=1663924&view=auto
==============================================================================
(empty)
Added:
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/reference/dependency-resource.mdtext
URL:
http://svn.apache.org/viewvc/felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/reference/dependency-resource.mdtext?rev=1663924&view=auto
==============================================================================
(empty)
Added:
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/reference/dependency-service.mdtext
URL:
http://svn.apache.org/viewvc/felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/reference/dependency-service.mdtext?rev=1663924&view=auto
==============================================================================
(empty)
Added:
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/reference/external-links.mdtext
URL:
http://svn.apache.org/viewvc/felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/reference/external-links.mdtext?rev=1663924&view=auto
==============================================================================
(empty)
Added:
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/tutorials/getting-started.mdtext
URL:
http://svn.apache.org/viewvc/felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/tutorials/getting-started.mdtext?rev=1663924&view=auto
==============================================================================
---
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/tutorials/getting-started.mdtext
(added)
+++
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/tutorials/getting-started.mdtext
Wed Mar 4 10:39:19 2015
@@ -0,0 +1,194 @@
+Title: Apache Felix Dependency Manager - Getting Started
+
+## Getting Started
+
+When developing an OSGi bundle that has dependencies and possibly registers
services, there are two classes in particular we need to implement:
+
+1. The bundle activator which controls the life-cycle of the bundle.
+1. The actual component, which can be a POJO.
+
+When using the dependency manager, your bundle activator is a subclass of
`DependencyActivatorBase`. It needs to implement the `init` life cycle method
and can optionally also implement a `destroy` method. Both methods take two
arguments: `BundleContext` and `DependencyManager`. The latter is your
interface to the declarative API you can use to define your components and
dependencies.
+
+The following paragraphs will show various examples that explain how to do
this. Subsequently, some more advanced scenarios will be covered that involve
listening to dependency and component state changes and interacting with the
OSGi framework from within your component implementation.
+
+### Registering a service
+
+The first example is about registering a service. We extend
`DependencyActivatorBase` and in the init method we use the reference to the
`DependencyManager` to create and add a component. For this component we
subsequently set its service interface and implementation. In this case the
interface is the `Store` interface, the second parameter, null, allows you to
provide properties along with the service registration. For the implementation,
we only mention the `Class` of the implementation, which means the dependency
manager will lazily instantiate it. In this case, there is not much point in
doing that because the component has no dependencies, but if it had, the
instantiation would only happen when those dependencies were resolved.
+
+Notice that the dependency manager API uses method chaining to create a more
or less "fluent" API that, with proper indentation, is very easy to read.
+
+
+ public class Activator extends DependencyActivatorBase {
+ public void init(BundleContext context, DependencyManager manager)
throws Exception {
+ manager.add(createComponent()
+ .setInterface(Store.class.getName(), null)
+ .setImplementation(MemoryStore.class)
+ );
+ }
+
+ public void destroy(BundleContext context, DependencyManager manager)
throws Exception {}
+ }
+
+
+This is the service interface. Nothing special here.
+
+
+ public interface Store {
+ public void put(String key, Object value);
+ public Object get(String key);
+ }
+
+
+And finally the implementation. Again, this is just a POJO, there is no
reference here to any OSGi or dependency manager specific class or annotation.
+
+
+ public class MemoryStore implements Store {
+ private Map m_map = new HashMap();
+
+ public Object get(String key) {
+ return m_map.get(key);
+ }
+
+ public void put(String key, Object value) {
+ m_map.put(key, value);
+ }
+ }
+
+
+### Depending on a service
+
+Our second example is that of a component that depends on two other services:
our `Store` from the previous example and the standard OSGi `LogService`.
Looking at the code, there is a small but important difference between the two:
`Store` is a required dependency and `LogService` is not. This means that our
component really needs a store to work, but if there is no logging available,
it can work without. Also note that this component has no `setInterface`
method, which simply means it is not itself a service. This is perfectly fine.
+
+
+ public class Activator extends DependencyActivatorBase {
+ public void init(BundleContext context, DependencyManager manager)
throws Exception {
+ manager.add(createComponent()
+ .setImplementation(DataGenerator.class)
+ .add(createServiceDependency()
+ .setService(Store.class)
+ .setRequired(true)
+ )
+ .add(createServiceDependency()
+ .setService(LogService.class)
+ .setRequired(false)
+ )
+ );
+ }
+
+ public void destroy(BundleContext context, DependencyManager manager)
throws Exception {}
+ }
+
+
+Now let's look at our POJO. There are a couple of interesting things to
explain. First of all, our dependencies are declared as fields, and they don't
even have setters (or getters). When the dependency manager instantiates our
class, it will (through reflection) inject the dependencies so they are just
available for our class to use. That is also the reason these fields are
declared as volatile: to make sure they are visible to all threads traversing
our instance.
+
+One final note, since we defined our `LogService` dependency as optional, it
might not be available when we invoke it. Still, the code does not contain any
checks to avoid a null pointer exception. It does not need to, since the
dependency manager makes sure to inject a null object when the real service is
not available. The null object can be invoked and will do nothing. For a lot of
cases that is good enough, but for those cases where it is not, our next
example introduces callbacks that notify you of changes.
+
+
+ public class DataGenerator {
+ private volatile Store m_store;
+ private volatile LogService m_log;
+
+ public void generate() {
+ for (int i = 0; i < 10; i++) {
+ m_store.put("#" + i, "value_" + i);
+ }
+ m_log.log(LogService.LOG_INFO, "Data generated.");
+ }
+ }
+
+
+### Tracking services with callbacks
+
+Sometimes, simply injecting services does not give you enough control over a
dependency because you might want to track more than one, or you might want to
execute some code on changes. For all those cases, callbacks are your friends.
Since one of our goals is to not introduce any kind of API in our POJO,
callbacks are declared by specifying their method names instead of through some
interface. In this case, we have a dependency on `Translator` services, and we
define `added` and `removed` as callbacks.
+
+
+ public class Activator extends DependencyActivatorBase {
+ public void init(BundleContext context, DependencyManager manager)
throws Exception {
+ manager.add(createComponent()
+ .setImplementation(DocumentTranslator.class)
+ .add(createServiceDependency()
+ .setService(Translator.class)
+ .setRequired(false)
+ .setCallbacks("added", "removed")
+ )
+ );
+ }
+
+ public void destroy(BundleContext context, DependencyManager manager)
throws Exception {}
+ }
+
+
+This is the actual `Translator` service, which, for the purpose of this
example, is not that important.
+
+
+ public interface Translator {
+ public boolean canTranslate(String from, String to);
+ public Document translate(Document document, String from, String to);
+ }
+
+
+Finally, here's our implementation. It declares the callback methods with one
parameter: the `Translator` service. Actually, the dependency manager will look
for several different signatures (all explained in more detail in the reference
section).
+
+
+ public class DocumentTranslator {
+ private List<Translator> m_translators = new ArrayList<Translator>();
+
+ public void added(Translator translator) {
+ m_translators.add(translator);
+ }
+
+ public void removed(Translator translator) {
+ m_translators.remove(translator);
+ }
+
+ public Document translate(Document document, String from, String to) {
+ for (Translator translator : m_translators) {
+ if (translator.canTranslate(from, to)) {
+ return translator.translate(document, from, to);
+ }
+ }
+ return null;
+ }
+ }
+
+
+
+### Depending on a configuration
+
+Not all dependencies are on services. There are several other types of
dependencies that are supported, one of them is the configuration dependency.
In fact, only *required* configuration dependencies are supported, because
optional ones can just be achieved by registering as a `ManagedService`
yourself. When defining the dependency, you must define the persistent ID of
the service. The component will not become active until the configuration you
depend on is available *and* is valid. The latter can be checked by your
implementation as we will see below.
+
+
+ public class Activator extends DependencyActivatorBase {
+ public void init(BundleContext context, DependencyManager manager)
throws Exception {
+ manager.add(createComponent()
+ .setImplementation(Task.class)
+ .add(createConfigurationDependency()
+ .setPid("config.pid")
+ )
+ );
+ }
+
+ public void destroy(BundleContext context, DependencyManager manager)
throws Exception {}
+ }
+
+
+Here's our code that implements `ManagedService` and has an `updated` method.
This method checks if the provided configuration is valid and throw a
`ConfigurationException` if it is not. As long as this method does not accept
the configuration, the corresponding component will not be activated.
+
+
+ public class Task implements ManagedService {
+ private String m_interval;
+
+ public void execute() {
+ System.out.println("Scheduling task with interval " + m_interval);
+ }
+
+ public void updated(Dictionary properties) throws
ConfigurationException {
+ if (properties != null) {
+ m_interval = (String) properties.get("interval");
+ if (m_interval == null) {
+ throw new ConfigurationException("interval", "must be
specified");
+ }
+ }
+ }
+ }
+
Added:
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/tutorials/leveraging-the-shell.mdtext
URL:
http://svn.apache.org/viewvc/felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/tutorials/leveraging-the-shell.mdtext?rev=1663924&view=auto
==============================================================================
---
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/tutorials/leveraging-the-shell.mdtext
(added)
+++
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/tutorials/leveraging-the-shell.mdtext
Wed Mar 4 10:39:19 2015
@@ -0,0 +1,105 @@
+Title: Apache Felix Dependency Manager - Leveraging the shell
+
+# Introduction
+
+The shell bundle for the dependency manager extends the gogo shell with one
new command called "dm". This command can be used to get insight in the actual
components and services in a running OSGi framework.
+
+Typing help ```help dm``` in the gogo shell gives an overview of the available
command options.
+
+```
+dm - List dependency manager components
+ scope: dependencymanager
+ flags:
+ compact, cp Displays components using a compact form
+ nodeps, nd Hides component dependencies
+ notavail, na Only displays unavailable components
+ stats, stat, st Displays components statistics
+ wtf Detects where are the root failures
+ options:
+ bundleIds, bid, bi, b <List of bundle ids or bundle symbolic names to
display (comma separated)> [optional]
+ componentIds, cid, ci <List of component identifiers to display (comma
separated)> [optional]
+ components, c <Regex(s) used to filter on component implementation
class names (comma separated), can be negated using "!" prefix> [optional]
+ services, s <OSGi filter used to filter some service properties>
[optional]
+ top <Max number of top components to display (0=all)> This command
displays components callbacks (init/start) times> [optional]
+ parameters:
+ CommandSession
+```
+
+
+# Usage examples
+Below are some examples for typical usage of the dependency manager shell
commands. The examples are based on a simple component model with a dashboard
which has a required dependency on four probes (temperature, humidity,
radiation, pressure). The radiation probe requires a Sensor service but this
sensor is not available.
+
+__List all dependency manager components__
+
+```dm```
+
+Sample output
+
+```
+[9] dm.demo
+ [6] dm.demo.Probe(type=radiation) unregistered
+ dm.demo.Sensor service required unavailable
+ [7] dm.demo.Probe(type=humidity) registered
+ [9] dm.demo.impl.Dashboard unregistered
+ dm.demo.Probe (type=temperature) service required available
+ dm.demo.Probe (type=radiation) service required unavailable
+ dm.demo.Probe (type=humidity) service required available
+ dm.demo.Probe (type=pressure) service required available
+ [5] dm.demo.Probe(type=temperature) registered
+ [8] dm.demo.Probe(type=pressure) registered
+```
+All components are listed including the dependencies and the availability of
these dependencies. The top level element is the bundle and below are the
components registered with that bundle's bundle context. The lowest level is
that of the component's dependencies.
+
+```
+[bundleid] bundle
+ [component id] component interfaces (service properties)
+ dependency <availability>
+```
+
+The following flags can be used to tailor the output.
+
+```compact, cp``` shortens package names and dependencies and therefore gives
a more compressed output.
+
+```nodeps, nd``` omits the dependencies from the output.
+
+```notavail, na``` filters out all components that are registered wich results
in the output only containing those components that are in the unregistered
state due to one or more unsatisfied required dependencies. This is the command
option most used when using the dependency manager shell commands.
+
+Sample output for ```dm na```:
+
+```
+[9] dm.demo
+ [14] dm.demo.impl.Dashboard unregistered
+ dm.demo.Probe (type=radiation) service required unavailable
+ [11] dm.demo.Probe(type=radiation) unregistered
+ dm.demo.Sensor service required unavailable
+```
+
+The flags can be used in conjunction with the other command options.
+
+__Find all components for a given classname__
+
+```dm c .*ProbeImpl```
+
+dm c or components finds all components for which the classname of the
implementation matches the regular expression.
+
+__Find all services matching a service filter__
+
+```dm s "(type=temperature)"```
+
+dm s allows finding components based on the service properties of their
registered services in the service registry using a standard OSGi service
filter.
+
+__Find out why components are not registered__
+
+```dm wtf```
+
+Sample output
+
+```
+2 missing dependencies found.
+-----------------------------
+The following service(s) are missing:
+ * dm.demo.Sensor is not found in the service registry
+```
+
+wtf gives the root cause for components not being registered and therefore
their services not being available. In a typical application components have
dependencies on services implemented by components that have dependencies on
services etcetera. This transitivity means that an entire chain of components
could be unregistered due to a (few) root dependencies not being satisified.
wtf is about discovering those dependencies.
+
\ No newline at end of file
Added:
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/tutorials/working-with-annotations.mdtext
URL:
http://svn.apache.org/viewvc/felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/tutorials/working-with-annotations.mdtext?rev=1663924&view=auto
==============================================================================
---
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/tutorials/working-with-annotations.mdtext
(added)
+++
felix/site/trunk/content/documentation/subprojects/apache-felix-dependency-manager-4/tutorials/working-with-annotations.mdtext
Wed Mar 4 10:39:19 2015
@@ -0,0 +1,122 @@
+Title: Apache Felix Dependency Manager - Annotations
+
+The Dependency Manager provides a compact and versatile Java API that allows
you to declaratively and programmatically register, acquire, and manage dynamic
OSGi components. This has many advantages, but also means you need to implement
your own `BundleActivator`. In cases where your dependencies are not that
dynamic, an alternative is to use annotations on your component.
+
+This tutorial outlines how to setup and use such annotations to describe your
components and dependencies. We present a simple "Hello World" component
defined using annotations, and also explain how to build the bundle using
either Bnd, Ant, or Maven.
+
+## Hello World Component
+
+ package org.apache.felix.dependencymanager.samples.annotation.hello;
+
+ import org.apache.felix.dm.annotation.api.Component;
+ import org.apache.felix.dm.annotation.api.Start;
+
+ @Component
+ public class HelloWorld {
+ @Start
+ public void activate() {
+ System.out.println("Hello world !");
+ }
+ }
+
+
+## Compiling with Bnd:
+
+The annotations must be processed at compilation phase and you have to use a
special Bnd plugin (declared using the "-plugin" bnd directive):
+
+ Bundle-Name: Hello World Using Dependency Manager Annotations
+ Bundle-SymbolicName:
org.apache.felix.dependencymanager.samples.annotation.hello
+ Import-Package: *
+ Private-Package:
org.apache.felix.dependencymanager.samples.annotation.hello
+ -plugin org.apache.felix.dm.annotation.plugin.bnd.AnnotationPlugin;log=warn
+
+
+## Compiling with Ant:
+
+Since Bnd provides a Ant task, you can use the bnd directives above with the
following build.xml:
+(it is assumed that directives.bnd, bnd.jar, json-20070829.jar and
org.apache.felix.dependencymanager.annotation.jar are in the current directory)
+
+ <project name="TestDM" default="bnd">
+ <property name="bnd" value="bnd.jar" />
+ <property name="json" value="json-20070829.jar" />
+ <property name="dmannot"
value="org.apache.felix.dependencymanager.annotation.jar" />
+
+ <target name="compile">
+ <delete dir="target/classes" quiet="yes" />
+ <mkdir dir="target/classes" />
+ <javac srcdir="src/main/java" destdir="target/classes"
classpath="${dmannot}" />
+ </target>
+
+ <target name="bnd" depends="compile">
+ <taskdef resource="aQute/bnd/ant/taskdef.properties"
classpath="${dmannot}:${bnd}:${json}" />
+ <bnd classpath="target/classes" eclipse="false"
files="directives.bnd"
output="org.apache.felix.dependencymanager.samples.annotation.hello.jar" />
+ </target>
+ </project>
+
+
+## Compiling with Maven:
+
+When compiling with Maven, you have to use the Dependency Manager Maven
annotation plugin:
+
+ :::xml
+ <?xml version="1.0"?>
+ <project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <properties>
+ <osgi.version>4.2.0</osgi.version>
+ </properties>
+ <name>Hello World Using Dependency Manager Annotations</name>
+ <groupId>org.apache.felix</groupId>
+
<artifactId>org.apache.felix.dependencymanager.samples.annotation.hello</artifactId>
+ <version>3.0.0-SNAPSHOT</version>
+ <packaging>bundle</packaging>
+ <dependencies>
+ <dependency>
+ <groupId>${pom.groupId}</groupId>
+
<artifactId>org.apache.felix.dependencymanager.annotation</artifactId>
+ <version>3.0.0</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>2.3.4</version>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-Name>Hello World Using
Dependency Manager Annotations</Bundle-Name>
+
<Bundle-SymbolicName>org.apache.felix.dependencymanager.samples.annotation.hello</Bundle-SymbolicName>
+
<Import-Package>*</Import-Package>
+
<Private-Package>org.apache.felix.dependencymanager.samples.annotation.hello</Private-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+
<artifactId>org.apache.felix.dependencymanager.annotation</artifactId>
+ <version>3.0.0</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>scan</goal>
+ </goals>
+ <configuration>
+ <log>info</log>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </project>