| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="utf-8"> |
| <meta name="viewport" content="width=device-width,initial-scale=1"> |
| <title>Dependency Manager - Getting Started :: Apache Felix</title> |
| <link rel="canonical" href="https://felix.apache.org/documentation/subprojects/apache-felix-dependency-manager/tutorials/getting-started.html"> |
| <meta name="generator" content="Antora 2.3.4"> |
| <link rel="stylesheet" href="../../../../_/css/site.css"> |
| <link rel="icon" href="../../../../_/img/favicon.png" type="image/x-icon"> |
| </head> |
| <body class="article"> |
| <header class="header"> |
| <nav class="navbar"> |
| <div class="navbar-brand"> |
| <a class="navbar-item" href="https://felix.apache.org/index.html"> |
| <span> |
| <img src="../../../../_/img/logo.png"> |
| </span> |
| </a> |
| <button class="navbar-burger" data-target="topbar-nav"> |
| <span></span> |
| <span></span> |
| <span></span> |
| </button> |
| </div> |
| <div id="topbar-nav" class="navbar-menu"> |
| <div class="navbar-end"> |
| <a class="navbar-item" href="https://felix.apache.org/index.html">Home</a> |
| <div class="navbar-item has-dropdown is-hoverable"> |
| <a class="navbar-link" href="#">Subprojects</a> |
| <div class="navbar-dropdown"> |
| <a class="navbar-item" href="../../apache-felix-dependency-manager.html">Dependency Manager</a> |
| <a class="navbar-item" href="../../apache-felix-event-admin.html">Event Admin</a> |
| <a class="navbar-item" href="../../apache-felix-file-install.html">File Install</a> |
| <a class="navbar-item" href="../../apache-felix-framework.html">Framework</a> |
| <a class="navbar-item" href="../../apache-felix-gogo.html">Gogo Shell</a> |
| <a class="navbar-item" href="../../apache-felix-healthchecks.html">Health Checks</a> |
| <a class="navbar-item" href="../../apache-felix-inventory.html">Inventory</a> |
| <a class="navbar-item" href="../../apache-felix-log.html">Log</a> |
| <a class="navbar-item" href="../../apache-felix-logback.html">Logback</a> |
| <a class="navbar-item" href="../../apache-felix-maven-bundle-plugin.html">Maven bundle plugin</a> |
| <a class="navbar-item" href="../../apache-felix-maven-scr-plugin.html">Maven SCR plugin</a> |
| <a class="navbar-item" href="../../apache-felix-metatype-service.html">Metatype Service</a> |
| <a class="navbar-item" href="../../apache-felix-preferences-service.html">Preferences Service</a> |
| <a class="navbar-item" href="../../apache-felix-remote-shell.html">Remote Shell</a> |
| <a class="navbar-item" href="../../apache-felix-script-console-plugin.html">Script console plugin</a> |
| <a class="navbar-item" href="../../apache-felix-shell.html">Lightweight shell</a> |
| <a class="navbar-item" href="../../apache-felix-shell-tui.html">Shell TUI</a> |
| <a class="navbar-item" href="../../apache-felix-web-console.html">Web Console</a> |
| </div> |
| </div> |
| <div class="navbar-item"> |
| <span class="control"> |
| <a class="button is-primary" href="../../../downloads.html">Downloads</a> |
| </span> |
| </div> |
| </div> |
| </div> |
| </nav> |
| </header> |
| <div class="body"> |
| <div class="nav-container" data-component="documentation" data-version="master"> |
| <aside class="nav"> |
| <div class="panels"> |
| <div class="nav-panel-menu is-active" data-panel="menu"> |
| <nav class="nav-menu"> |
| <h3 class="title"><a href="../../../index.html">Documentation</a></h3> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="0"> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="../../../documentation.html">Documentation</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="../../../downloads.html">Downloads</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="../../../getting-started.html">Getting Started</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="../../../news.html">News</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <button class="nav-item-toggle"></button> |
| <span class="nav-text">Community</span> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../../community/project-info.html">Apache Felix Project Info</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../../community/contributing.html">Contributing</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../../community/projects-using-felix.html">Projects Using Felix</a> |
| </li> |
| </ul> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <button class="nav-item-toggle"></button> |
| <span class="nav-text">Development</span> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../../development/coding-standards.html">Coding Standards</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../../development/dependencies-file-template.html">DEPENDENCIES file template</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../../development/provisional-osgi-api-policy.html">Provisional OSGi API Policy</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../../development/release-management-nexus.html">Release Management</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../../development/site-how-to.html">Site How To</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../../development/using-the-osgi-compliance-tests.html">Using the OSGi Compliance Tests</a> |
| </li> |
| </ul> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <button class="nav-item-toggle"></button> |
| <a class="nav-link" href="../../../faqs.html">FAQS</a> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../../faqs/apache-felix-bundle-plugin-faq.html">Apache Felix Bundle Plugin Frequently Asked Questions</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../../faqs/apache-felix-scr-plugin-faq.html">Apache Felix SCR Plugin Frequently Asked Questions</a> |
| </li> |
| </ul> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <button class="nav-item-toggle"></button> |
| <a class="nav-link" href="../../../subprojects.html">Subprojects</a> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="2"> |
| <button class="nav-item-toggle"></button> |
| <a class="nav-link" href="../../apache-felix-dependency-manager.html">Apache Felix Dependency Manager</a> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="3"> |
| <button class="nav-item-toggle"></button> |
| <span class="nav-text">Guides</span> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="../guides/migrating-from-earlier-versions.html">Apache Felix Dependency Manager - Migrating from earlier versions</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="../guides/annotations.html">Dependency Manager - Annotations</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="../guides/background.html">Dependency Manager - Background</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="../guides/bundles-and-dependencies.html">Dependency Manager - Bundles and Dependencies</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="../guides/design-patterns.html">Dependency Manager - Design Patterns</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="../guides/development.html">Dependency Manager - Development</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="../guides/history.html">Dependency Manager - History</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="../guides/javadocs.html">Dependency Manager - JavaDocs</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="../guides/migrating-from-other-solutions.html">Dependency Manager - Migrating from other solutions.</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="../guides/performance-tuning.html">Dependency Manager - Performance Tuning</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="../guides/resources.html">Dependency Manager - Resource adapters</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="../guides/whatsnew.html">Dependency Manager - What’s new in version 4?</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="../guides/dm-lambda.html">Dependency Manager Lambda</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="../guides/whatsnew-r15.html">What’s New in R15</a> |
| </li> |
| </ul> |
| </li> |
| <li class="nav-item" data-depth="3"> |
| <button class="nav-item-toggle"></button> |
| <span class="nav-text">Reference</span> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="../reference/component-adapter.html">Dependency Manager - Adapter</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="../reference/component-aspect.html">Dependency Manager - Aspect</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="../reference/component-bundle-adapter.html">Dependency Manager - Bundle Adapter</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="../reference/dependency-bundle.html">Dependency Manager - Bundle Dependency</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="../reference/components.html">Dependency Manager - Components</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="../reference/dependency-configuration.html">Dependency Manager - Configuration Dependency</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="../reference/dependencies.html">Dependency Manager - Dependencies</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="../reference/external-links.html">Dependency Manager - External Links</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="../reference/component-factory-configuration-adapter.html">Dependency Manager - Factory Configuration Adapter Service</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="../reference/component-resource-adapter.html">Dependency Manager - Resource Adapter</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="../reference/dependency-resource.html">Dependency Manager - Resource Dependency</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="../reference/dependency-service.html">Dependency Manager - Service Dependency</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="../reference/service-scopes.html">Dependency Manager - Service Scopes</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="../reference/component-singleton.html">Dependency Manager - Singleton Component</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="../reference/thread-model.html">Dependency Manager - Thread Model</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="../reference/dm-annotations.html">Dependency Manager Annotations</a> |
| </li> |
| </ul> |
| </li> |
| <li class="nav-item" data-depth="3"> |
| <button class="nav-item-toggle"></button> |
| <span class="nav-text">Tutorials</span> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="working-with-annotations.html">Dependency Manager - Annotations</a> |
| </li> |
| <li class="nav-item is-current-page" data-depth="4"> |
| <a class="nav-link" href="getting-started.html">Dependency Manager - Getting Started</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="leveraging-the-shell.html">Dependency Manager - Leveraging the shell</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="sample-code.html">Dependency Manager sample projects</a> |
| </li> |
| </ul> |
| </li> |
| </ul> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../apache-felix-event-admin.html">Apache Felix Event Admin</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../apache-felix-file-install.html">Apache Felix File Install</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <button class="nav-item-toggle"></button> |
| <a class="nav-link" href="../../apache-felix-framework.html">Apache Felix Framework</a> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="../../apache-felix-framework/apache-felix-framework-bundle-cache.html">Apache Felix Framework Bundle Cache</a> |
| </li> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="../../apache-felix-framework/apache-felix-framework-configuration-properties.html">Apache Felix Framework Configuration Properties</a> |
| </li> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="../../apache-felix-framework/apache-felix-framework-faq.html">Apache Felix Framework Frequently Asked Questions</a> |
| </li> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="../../apache-felix-framework/apache-felix-framework-launching-and-embedding.html">Apache Felix Framework Launching and Embedding</a> |
| </li> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="../../apache-felix-framework/apache-felix-framework-usage-documentation.html">Apache Felix Framework Usage Documentation</a> |
| </li> |
| </ul> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../apache-felix-framework-security.html">Apache Felix Framework Security</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <button class="nav-item-toggle"></button> |
| <a class="nav-link" href="../../apache-felix-gogo.html">Apache Felix Gogo</a> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="../../apache-felix-gogo/rfc-147-overview.html">RFC 147 Overview</a> |
| </li> |
| </ul> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../apache-felix-healthchecks.html">Apache Felix Health Checks</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../apache-felix-inventory.html">Apache Felix Inventory Printer</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../apache-felix-log.html">Apache Felix Log</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../apache-felix-logback.html">Apache Felix Logback</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../apache-felix-maven-bundle-plugin-bnd.html">Apache Felix Maven Bundle Plugin (BND)</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../apache-felix-metatype-service.html">Apache Felix Metatype Service</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../apache-felix-osgi-bundle-repository.html">Apache Felix OSGi Bundle Repository (OBR)</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../apache-felix-preferences-service.html">Apache Felix Preferences Service</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../apache-felix-remote-shell.html">Apache Felix Remote Shell</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../apache-felix-shell.html">Apache Felix Shell</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../apache-felix-shell-tui.html">Apache Felix Shell TUI</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <button class="nav-item-toggle"></button> |
| <a class="nav-link" href="../../apache-felix-web-console.html">Apache Felix Web Console</a> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="../../apache-felix-web-console/extending-the-apache-felix-web-console.html">Extending the Apache Felix Web Console</a> |
| </li> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="../../apache-felix-web-console/web-console-restful-api.html">Web Console RESTful API</a> |
| </li> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="../../apache-felix-web-console/web-console-security-provider.html">Web Console Security Provider</a> |
| </li> |
| <li class="nav-item" data-depth="3"> |
| <button class="nav-item-toggle"></button> |
| <span class="nav-text">Extensions</span> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="../../apache-felix-web-console/extending-the-apache-felix-web-console/branding-the-web-console.html">Branding the Web Console</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="../../apache-felix-web-console/extending-the-apache-felix-web-console/providing-resources.html">Providing Resources</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="../../apache-felix-web-console/extending-the-apache-felix-web-console/providing-web-console-plugins.html">Providing Web Console Plugins</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="../../apache-felix-web-console/extending-the-apache-felix-web-console/web-console-logging.html">Web Console Logging</a> |
| </li> |
| <li class="nav-item" data-depth="4"> |
| <a class="nav-link" href="../../apache-felix-web-console/extending-the-apache-felix-web-console/web-console-output-templating.html">Web Console Output Templating</a> |
| </li> |
| </ul> |
| </li> |
| </ul> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <button class="nav-item-toggle"></button> |
| <span class="nav-text">Maven SCR plugin</span> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="../../apache-felix-maven-scr-plugin/apache-felix-maven-scr-plugin-use.html">Apache Felix Maven SCR Plugin Use</a> |
| </li> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="../../apache-felix-maven-scr-plugin/apache-felix-scr-bndtools-use.html">Apache Felix SCR Annotations BndTools Use</a> |
| </li> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="../../apache-felix-maven-scr-plugin/apache-felix-scr-ant-task-use.html">Apache Felix SCR Ant Task Use</a> |
| </li> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="../../apache-felix-maven-scr-plugin/extending-scr-annotations.html">Extending SCR Annotations Excerpt: How add new Annotations extending the base Annotations</a> |
| </li> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="../../apache-felix-maven-scr-plugin/scr-annotations.html">SCR Annotations Excerpt: Using Java 5 Annotations to describe the component or service.</a> |
| </li> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="../../apache-felix-maven-scr-plugin/scr-javadoc-tags.html">SCR JavaDoc Tags Excerpt: Using JavaDoc Tags to describe the component or service.</a> |
| </li> |
| </ul> |
| </li> |
| </ul> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <button class="nav-item-toggle"></button> |
| <a class="nav-link" href="../../../tutorials-examples-and-presentations.html">Tutorials</a> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../../tutorials-examples-and-presentations/apache-felix-application-demonstration.html">Apache Felix Application Demonstration</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../../tutorials-examples-and-presentations/apache-felix-osgi-tutorial.html">Apache Felix OSGi Tutorial</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <a class="nav-link" href="../../../tutorials-examples-and-presentations/apache-felix-osgi-faq.html">OSGi Frequently Asked Questions</a> |
| </li> |
| <li class="nav-item" data-depth="2"> |
| <button class="nav-item-toggle"></button> |
| <span class="nav-text">OSGI Tutorial</span> |
| <ul class="nav-list"> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="../../../tutorials-examples-and-presentations/apache-felix-osgi-tutorial/apache-felix-tutorial-example-1.html">Apache Felix Tutorial Example 1 - Service Event Listener Bundle</a> |
| </li> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="../../../tutorials-examples-and-presentations/apache-felix-osgi-tutorial/apache-felix-tutorial-example-2.html">Apache Felix Tutorial Example 2</a> |
| </li> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="../../../tutorials-examples-and-presentations/apache-felix-osgi-tutorial/apache-felix-tutorial-example-2b.html">Apache Felix Tutorial Example 2b</a> |
| </li> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="../../../tutorials-examples-and-presentations/apache-felix-osgi-tutorial/apache-felix-tutorial-example-3.html">Apache Felix Tutorial Example 3</a> |
| </li> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="../../../tutorials-examples-and-presentations/apache-felix-osgi-tutorial/apache-felix-tutorial-example-4.html">Apache Felix Tutorial Example 4</a> |
| </li> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="../../../tutorials-examples-and-presentations/apache-felix-osgi-tutorial/apache-felix-tutorial-example-5.html">Apache Felix Tutorial Example 5</a> |
| </li> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="../../../tutorials-examples-and-presentations/apache-felix-osgi-tutorial/apache-felix-tutorial-example-6.html">Example 6 - Spell Checker Service Bundle</a> |
| </li> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="../../../tutorials-examples-and-presentations/apache-felix-osgi-tutorial/apache-felix-tutorial-example-7.html">Example 7 - Spell Checker Client Bundle</a> |
| </li> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="../../../tutorials-examples-and-presentations/apache-felix-osgi-tutorial/apache-felix-tutorial-example-8.html">Example 8 - Spell Checker Service using Service Binder</a> |
| </li> |
| <li class="nav-item" data-depth="3"> |
| <a class="nav-link" href="../../../tutorials-examples-and-presentations/apache-felix-osgi-tutorial/apache-felix-tutorial-example-9.html">Example 9 - Spell Checker Service using Declarative Services</a> |
| </li> |
| </ul> |
| </li> |
| </ul> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="../../../license.html">Apache License 2.0</a> |
| </li> |
| <li class="nav-item" data-depth="1"> |
| <a class="nav-link" href="../../../site-map.html">Site map</a> |
| </li> |
| </ul> |
| </li> |
| </ul> |
| </nav> |
| </div> |
| <div class="nav-panel-explore" data-panel="explore"> |
| <div class="context"> |
| <span class="title">Documentation</span> |
| <span class="version">master</span> |
| </div> |
| <ul class="components"> |
| <li class="component is-current"> |
| <span class="title">Documentation</span> |
| <ul class="versions"> |
| <li class="version is-current is-latest"> |
| <a href="../../../index.html">master</a> |
| </li> |
| </ul> |
| </li> |
| </ul> |
| </div> |
| </div> |
| </aside> |
| </div> |
| <main class="article"> |
| <div class="toolbar" role="navigation"> |
| <button class="nav-toggle"></button> |
| <a href="../../../index.html" class="home-link"></a> |
| <nav class="breadcrumbs" aria-label="breadcrumbs"> |
| <ul> |
| <li><a href="../../../index.html">Documentation</a></li> |
| <li><a href="../../../subprojects.html">Subprojects</a></li> |
| <li><a href="../../apache-felix-dependency-manager.html">Apache Felix Dependency Manager</a></li> |
| <li>Tutorials</li> |
| <li><a href="getting-started.html">Dependency Manager - Getting Started</a></li> |
| </ul> |
| </nav> |
| <div class="edit-this-page"><a href="https://github.com/apache/felix-antora-site/edit/main/modules/ROOT/pages/subprojects/apache-felix-dependency-manager/tutorials/getting-started.adoc">Edit this Page</a></div> |
| </div> |
| <div class="content"> |
| <article class="doc"> |
| <h1 class="page">Dependency Manager - Getting Started</h1> |
| <div id="preamble"> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>When developing an OSGi bundle that has dependencies and possibly registers services, there are two classes in particular we need to implement:</p> |
| </div> |
| <div class="olist arabic"> |
| <ol class="arabic"> |
| <li> |
| <p>The bundle activator which controls the life-cycle of the bundle.</p> |
| </li> |
| <li> |
| <p>The actual component, which can be a POJO.</p> |
| </li> |
| </ol> |
| </div> |
| <div class="paragraph"> |
| <p>When using the dependency manager, your bundle activator is a subclass of <code>DependencyActivatorBase</code>. |
| It needs to implement the <code>init</code> life cycle method and can optionally also implement a <code>destroy</code> method. |
| Both methods take two arguments: <code>BundleContext</code> and <code>DependencyManager</code>. |
| The latter is your interface to the declarative API you can use to define your components and dependencies.</p> |
| </div> |
| <div class="paragraph"> |
| <p>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.</p> |
| </div> |
| <div class="paragraph"> |
| <p>To use the dependency manager, you should put the <code>org.apache.felix.dependencymanager.jar</code> in your classpath while compiling and in your OSGi framework when running.</p> |
| </div> |
| <div class="paragraph"> |
| <p>A recent java 8 jdk is required since the dependency manager r8 (the dm r8 release has been built and tested using java version 1.8.74).</p> |
| </div> |
| </div> |
| </div> |
| <div class="sect1"> |
| <h2 id="_registering_a_service"><a class="anchor" href="#_registering_a_service"></a>Registering a service</h2> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>The first example is about registering a service. |
| We extend <code>DependencyActivatorBase</code> and in the <code>init</code> method we use the reference to the <code>DependencyManager</code> to create and add a component. |
| For this component we subsequently set its service interface and implementation. |
| In this case the interface is the <code>Store</code> interface, the second parameter, <code>null</code>, allows you to provide properties along with the service registration. |
| For the implementation, we only mention the <code>Class</code> 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.</p> |
| </div> |
| <div class="paragraph"> |
| <p>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.</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java"> public class Activator extends DependencyActivatorBase { |
| public void init(BundleContext context, DependencyManager manager) throws Exception { |
| manager.add(createComponent() |
| .setInterface(Store.class, null) |
| .setImplementation(MemoryStore.class) |
| ); |
| } |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>This is the service interface. |
| Nothing special here.</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java"> public interface Store { |
| public void put(String key, Object value); |
| public Object get(String key); |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>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.</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">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); |
| } |
| }</code></pre> |
| </div> |
| </div> |
| </div> |
| </div> |
| <div class="sect1"> |
| <h2 id="_depending_on_a_service"><a class="anchor" href="#_depending_on_a_service"></a>Depending on a service</h2> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>Our second example is that of a component that depends on two other services: our <code>Store</code> from the previous example and the standard OSGi <code>LogService</code>. |
| Looking at the code, there is a small but important difference between the two: <code>Store</code> is a required dependency and <code>LogService</code> 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 <code>setInterface</code> method, which simply means it is not itself a service. |
| This is perfectly fine.</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java"> 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) |
| ) |
| ); |
| } |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>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.</p> |
| </div> |
| <div class="paragraph"> |
| <p>One final note, since we defined our <code>LogService</code> 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.</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java"> 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."); |
| } |
| }</code></pre> |
| </div> |
| </div> |
| </div> |
| </div> |
| <div class="sect1"> |
| <h2 id="_tracking_services_with_callbacks"><a class="anchor" href="#_tracking_services_with_callbacks"></a>Tracking services with callbacks</h2> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>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 <code>Translator</code> services, and we define <code>added</code> and <code>removed</code> as callbacks.</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java"> 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") |
| ) |
| ); |
| } |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>This is the actual <code>Translator</code> service, which, for the purpose of this example, is not that important.</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java"> public interface Translator { |
| public boolean canTranslate(String from, String to); |
| public Document translate(Document document, String from, String to); |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>Finally, here’s our implementation. |
| It declares the callback methods with one parameter: the <code>Translator</code> service. |
| Actually, the dependency manager will look for several different signatures (all explained in more detail in the reference section).</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java"> 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; |
| } |
| }</code></pre> |
| </div> |
| </div> |
| </div> |
| </div> |
| <div class="sect1"> |
| <h2 id="_depending_on_a_configuration"><a class="anchor" href="#_depending_on_a_configuration"></a>Depending on a configuration</h2> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>Not all dependencies are on services. |
| There are several other types of dependencies that are supported, one of them is the configuration dependency. |
| 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 <em>and</em> is valid. |
| The latter can be checked by your implementation as we will see below.</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java"> 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") |
| ) |
| ); |
| } |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>Here’s our code that implements <code>ManagedService</code> and has an <code>updated</code> method. |
| This method checks if the provided configuration is valid and throw a <code>ConfigurationException</code> if it is not. |
| As long as this method does not accept the configuration, the corresponding component will not be activated. |
| Notice that your component does not necessarily implement the ManagedService interface, and the updated callback can also throw any exceptions:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">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"); |
| } |
| } |
| } |
| }</code></pre> |
| </div> |
| </div> |
| </div> |
| </div> |
| </article> |
| <aside class="toc sidebar" data-title="Contents" data-levels="2"> |
| <div class="toc-menu"></div> |
| </aside> |
| </div> |
| </main> |
| </div> |
| <footer class="footer"> |
| <p>Content licensed under AL2. UI licensed under MPL-2.0 with extensions licensed under AL2</p> |
| </footer> |
| <script src="../../../../_/js/site.js"></script> |
| <script async src="../../../../_/js/vendor/highlight.js"></script> |
| </body> |
| </html> |