blob: b17dc276bee805baa86655f4cf9524cac8a2e963 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Apache Felix Tutorial Example 4 :: Apache Felix</title>
<link rel="canonical" href="https://felix.apache.org/documentation/tutorials-examples-and-presentations/apache-felix-osgi-tutorial/apache-felix-tutorial-example-4.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="../../subprojects/apache-felix-dependency-manager.html">Dependency Manager</a>
<a class="navbar-item" href="../../subprojects/apache-felix-event-admin.html">Event Admin</a>
<a class="navbar-item" href="../../subprojects/apache-felix-file-install.html">File Install</a>
<a class="navbar-item" href="../../subprojects/apache-felix-framework.html">Framework</a>
<a class="navbar-item" href="../../subprojects/apache-felix-gogo.html">Gogo Shell</a>
<a class="navbar-item" href="../../subprojects/apache-felix-healthchecks.html">Health Checks</a>
<a class="navbar-item" href="../../subprojects/apache-felix-inventory.html">Inventory</a>
<a class="navbar-item" href="../../subprojects/apache-felix-log.html">Log</a>
<a class="navbar-item" href="../../subprojects/apache-felix-logback.html">Logback</a>
<a class="navbar-item" href="../../subprojects/apache-felix-maven-bundle-plugin.html">Maven bundle plugin</a>
<a class="navbar-item" href="../../subprojects/apache-felix-maven-scr-plugin.html">Maven SCR plugin</a>
<a class="navbar-item" href="../../subprojects/apache-felix-metatype-service.html">Metatype Service</a>
<a class="navbar-item" href="../../subprojects/apache-felix-preferences-service.html">Preferences Service</a>
<a class="navbar-item" href="../../subprojects/apache-felix-remote-shell.html">Remote Shell</a>
<a class="navbar-item" href="../../subprojects/apache-felix-script-console-plugin.html">Script console plugin</a>
<a class="navbar-item" href="../../subprojects/apache-felix-shell.html">Lightweight shell</a>
<a class="navbar-item" href="../../subprojects/apache-felix-shell-tui.html">Shell TUI</a>
<a class="navbar-item" href="../../subprojects/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="../../subprojects/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="../../subprojects/apache-felix-dependency-manager/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="../../subprojects/apache-felix-dependency-manager/guides/annotations.html">Dependency Manager - Annotations</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../subprojects/apache-felix-dependency-manager/guides/background.html">Dependency Manager - Background</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../subprojects/apache-felix-dependency-manager/guides/bundles-and-dependencies.html">Dependency Manager - Bundles and Dependencies</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../subprojects/apache-felix-dependency-manager/guides/design-patterns.html">Dependency Manager - Design Patterns</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../subprojects/apache-felix-dependency-manager/guides/development.html">Dependency Manager - Development</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../subprojects/apache-felix-dependency-manager/guides/history.html">Dependency Manager - History</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../subprojects/apache-felix-dependency-manager/guides/javadocs.html">Dependency Manager - JavaDocs</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../subprojects/apache-felix-dependency-manager/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="../../subprojects/apache-felix-dependency-manager/guides/performance-tuning.html">Dependency Manager - Performance Tuning</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../subprojects/apache-felix-dependency-manager/guides/resources.html">Dependency Manager - Resource adapters</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../subprojects/apache-felix-dependency-manager/guides/whatsnew.html">Dependency Manager - What&#8217;s new in version 4?</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../subprojects/apache-felix-dependency-manager/guides/dm-lambda.html">Dependency Manager Lambda</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../subprojects/apache-felix-dependency-manager/guides/whatsnew-r15.html">What&#8217;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="../../subprojects/apache-felix-dependency-manager/reference/component-adapter.html">Dependency Manager - Adapter</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../subprojects/apache-felix-dependency-manager/reference/component-aspect.html">Dependency Manager - Aspect</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../subprojects/apache-felix-dependency-manager/reference/component-bundle-adapter.html">Dependency Manager - Bundle Adapter</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../subprojects/apache-felix-dependency-manager/reference/dependency-bundle.html">Dependency Manager - Bundle Dependency</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../subprojects/apache-felix-dependency-manager/reference/components.html">Dependency Manager - Components</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../subprojects/apache-felix-dependency-manager/reference/dependency-configuration.html">Dependency Manager - Configuration Dependency</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../subprojects/apache-felix-dependency-manager/reference/dependencies.html">Dependency Manager - Dependencies</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../subprojects/apache-felix-dependency-manager/reference/external-links.html">Dependency Manager - External Links</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../subprojects/apache-felix-dependency-manager/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="../../subprojects/apache-felix-dependency-manager/reference/component-resource-adapter.html">Dependency Manager - Resource Adapter</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../subprojects/apache-felix-dependency-manager/reference/dependency-resource.html">Dependency Manager - Resource Dependency</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../subprojects/apache-felix-dependency-manager/reference/dependency-service.html">Dependency Manager - Service Dependency</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../subprojects/apache-felix-dependency-manager/reference/service-scopes.html">Dependency Manager - Service Scopes</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../subprojects/apache-felix-dependency-manager/reference/component-singleton.html">Dependency Manager - Singleton Component</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../subprojects/apache-felix-dependency-manager/reference/thread-model.html">Dependency Manager - Thread Model</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../subprojects/apache-felix-dependency-manager/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="../../subprojects/apache-felix-dependency-manager/tutorials/working-with-annotations.html">Dependency Manager - Annotations</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../subprojects/apache-felix-dependency-manager/tutorials/getting-started.html">Dependency Manager - Getting Started</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../subprojects/apache-felix-dependency-manager/tutorials/leveraging-the-shell.html">Dependency Manager - Leveraging the shell</a>
</li>
<li class="nav-item" data-depth="4">
<a class="nav-link" href="../../subprojects/apache-felix-dependency-manager/tutorials/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="../../subprojects/apache-felix-event-admin.html">Apache Felix Event Admin</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../subprojects/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="../../subprojects/apache-felix-framework.html">Apache Felix Framework</a>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../subprojects/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="../../subprojects/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="../../subprojects/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="../../subprojects/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="../../subprojects/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="../../subprojects/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="../../subprojects/apache-felix-gogo.html">Apache Felix Gogo</a>
<ul class="nav-list">
<li class="nav-item" data-depth="3">
<a class="nav-link" href="../../subprojects/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="../../subprojects/apache-felix-healthchecks.html">Apache Felix Health Checks</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../subprojects/apache-felix-inventory.html">Apache Felix Inventory Printer</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../subprojects/apache-felix-log.html">Apache Felix Log</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../subprojects/apache-felix-logback.html">Apache Felix Logback</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../subprojects/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="../../subprojects/apache-felix-metatype-service.html">Apache Felix Metatype Service</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../subprojects/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="../../subprojects/apache-felix-preferences-service.html">Apache Felix Preferences Service</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../subprojects/apache-felix-remote-shell.html">Apache Felix Remote Shell</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../subprojects/apache-felix-shell.html">Apache Felix Shell</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../../subprojects/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="../../subprojects/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="../../subprojects/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="../../subprojects/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="../../subprojects/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="../../subprojects/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="../../subprojects/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="../../subprojects/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="../../subprojects/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="../../subprojects/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="../../subprojects/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="../../subprojects/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="../../subprojects/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="../../subprojects/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="../../subprojects/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="../../subprojects/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="../apache-felix-application-demonstration.html">Apache Felix Application Demonstration</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../apache-felix-osgi-tutorial.html">Apache Felix OSGi Tutorial</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../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="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="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="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="apache-felix-tutorial-example-3.html">Apache Felix Tutorial Example 3</a>
</li>
<li class="nav-item is-current-page" data-depth="3">
<a class="nav-link" href="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="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="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="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="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="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="../../tutorials-examples-and-presentations.html">Tutorials</a></li>
<li>OSGI Tutorial</li>
<li><a href="apache-felix-tutorial-example-4.html">Apache Felix Tutorial Example 4</a></li>
</ul>
</nav>
<div class="edit-this-page"><a href="https://github.com/apache/felix-antora-site/edit/main/modules/ROOT/pages/tutorials-examples-and-presentations/apache-felix-osgi-tutorial/apache-felix-tutorial-example-4.adoc">Edit this Page</a></div>
</div>
<div class="content">
<article class="doc">
<h1 class="page">Apache Felix Tutorial Example 4</h1>
<div class="sect1">
<h2 id="_example_4_robust_dictionary_client_bundle"><a class="anchor" href="#_example_4_robust_dictionary_client_bundle"></a>Example 4 - Robust Dictionary Client Bundle</h2>
<div class="sectionbody">
<div class="paragraph">
<p>In Example 3, we create a simple client bundle for our dictionary service.
The problem with that client was that it did not monitor the dynamic availability of the dictionary service, thus an error would occur if the dictionary service disappeared while the client was using it.
In this example we create a client for the dictionary service that monitors the dynamic availability of the dictionary service.
The result is a more robust client.</p>
</div>
<div class="paragraph">
<p>The functionality of the new dictionary client is essentially the same as the old client, it reads words from standard input and checks for their existence in the dictionary service.
Our bundle uses its bundle context to register itself as a service event listener;
monitoring service events allows the bundle to monitor the dynamic availability of the dictionary service.
Our client uses the first dictionary service it finds.
The source code for our bundle is as follows in a file called <code>Activator.java</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>/*
* Apache Felix OSGi tutorial.
**/
package tutorial.example4;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceEvent;
import tutorial.example2.service.DictionaryService;
/**
* This class implements a bundle that uses a dictionary
* service to check for the proper spelling of a word by
* checking for its existence in the dictionary. This bundle
* is more complex than the bundle in Example 3 because it
* monitors the dynamic availability of the dictionary
* services. In other words, if the service it is using
* departs, then it stops using it gracefully, or if it needs
* a service and one arrives, then it starts using it
* automatically. As before, the bundle uses the first service
* that it finds and uses the calling thread of the
* start() method to read words from standard input.
* You can stop checking words by entering an empty line, but
* to start checking words again you must stop and then restart
* the bundle.
**/
public class Activator implements BundleActivator, ServiceListener
{
// Bundle's context.
private BundleContext m_context = null;
// The service reference being used.
private ServiceReference m_ref = null;
// The service object being used.
private DictionaryService m_dictionary = null;
/**
* Implements BundleActivator.start(). Adds itself
* as a listener for service events, then queries for
* available dictionary services. If any dictionaries are
* found it gets a reference to the first one available and
* then starts its "word checking loop". If no dictionaries
* are found, then it just goes directly into its "word checking
* loop", but it will not be able to check any words until a
* dictionary service arrives; any arriving dictionary service
* will be automatically used by the client if a dictionary is
* not already in use. Once it has dictionary, it reads words
* from standard input and checks for their existence in the
* dictionary that it is using.
* (NOTE: It is very bad practice to use the calling thread
* to perform a lengthy process like this; this is only done
* for the purpose of the tutorial.)
* @param context the framework context for the bundle.
**/
public void start(BundleContext context) throws Exception
{
m_context = context;
// We synchronize while registering the service listener and
// performing our initial dictionary service lookup since we
// don't want to receive service events when looking up the
// dictionary service, if one exists.
synchronized (this)
{
// Listen for events pertaining to dictionary services.
m_context.addServiceListener(this,
"(&amp;(objectClass=" + DictionaryService.class.getName() + ")" +
"(Language=*))");
// Query for any service references matching any language.
ServiceReference[] refs = m_context.getServiceReferences(
DictionaryService.class.getName(), "(Language=*)");
// If we found any dictionary services, then just get
// a reference to the first one so we can use it.
if (refs != null)
{
m_ref = refs[0];
m_dictionary = (DictionaryService) m_context.getService(m_ref);
}
}
try
{
System.out.println("Enter a blank line to exit.");
String word = "";
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
// Loop endlessly.
while (true)
{
// Ask the user to enter a word.
System.out.print("Enter word: ");
word = in.readLine();
// If the user entered a blank line, then
// exit the loop.
if (word.length() == 0)
{
break;
}
// If there is no dictionary, then say so.
else if (m_dictionary == null)
{
System.out.println("No dictionary available.");
}
// Otherwise print whether the word is correct or not.
else if (m_dictionary.checkWord(word))
{
System.out.println("Correct.");
}
else
{
System.out.println("Incorrect.");
}
}
} catch (Exception ex) { }
}
/**
* Implements BundleActivator.stop(). Does nothing since
* the framework will automatically unget any used services.
* @param context the framework context for the bundle.
**/
public void stop(BundleContext context)
{
// NOTE: The service is automatically released.
}
/**
* Implements ServiceListener.serviceChanged(). Checks
* to see if the service we are using is leaving or tries to get
* a service if we need one.
* @param event the fired service event.
**/
public synchronized void serviceChanged(ServiceEvent event)
{
String[] objectClass =
(String[]) event.getServiceReference().getProperty("objectClass");
// If a dictionary service was registered, see if we
// need one. If so, get a reference to it.
if (event.getType() == ServiceEvent.REGISTERED)
{
if (m_ref == null)
{
// Get a reference to the service object.
m_ref = event.getServiceReference();
m_dictionary = (DictionaryService) m_context.getService(m_ref);
}
}
// If a dictionary service was unregistered, see if it
// was the one we were using. If so, unget the service
// and try to query to get another one.
else if (event.getType() == ServiceEvent.UNREGISTERING)
{
if (event.getServiceReference() == m_ref)
{
// Unget service object and null references.
m_context.ungetService(m_ref);
m_ref = null;
m_dictionary = null;
// Query to see if we can get another service.
ServiceReference[] refs = null;
try
{
refs = m_context.getServiceReferences(
DictionaryService.class.getName(), "(Language=*)");
}
catch (InvalidSyntaxException ex)
{
// This will never happen.
}
if (refs != null)
{
// Get a reference to the first service object.
m_ref = refs[0];
m_dictionary = (DictionaryService) m_context.getService(m_ref);
}
}
}
}
}</pre>
</div>
</div>
<div class="paragraph">
<p>The client listens for service events indicating the arrival or departure of dictionary services.
If a new dictionary service arrives, the bundle will start using that service if and only if it currently does not have a dictionary service.
If an existing dictionary service disappears, the bundle will check to see if the disappearing service is the one it is using;
if it is it stops using it and tries to query for another dictionary service, otherwise it ignores the event.</p>
</div>
<div class="paragraph">
<p>Like normal, we must create a <code>manifest.mf</code> file that contains the meta-data for our bundle:</p>
</div>
<div class="literalblock">
<div class="content">
<pre>Bundle-Name: Dynamic dictionary client
Bundle-Description: A bundle that uses the dictionary service whenever it becomes available
Bundle-Vendor: Apache Felix
Bundle-Version: 1.0.0
Bundle-Activator: tutorial.example4.Activator
Import-Package: org.osgi.framework,
tutorial.example2.service</pre>
</div>
</div>
<div class="paragraph">
<p>We specify the class to activate our bundle via the <code>Bundle-Activator</code> attribute and also specify that our bundle imports the core OSGi framework package and the dictionary service interface package using the <code>Import-Package</code> attribute.
The OSGi framework will automatically handle the details of resolving import packages.
(Note: Make sure your manifest file ends in a trailing carriage return or else the last line will be ignored.)</p>
</div>
<div class="paragraph">
<p>To compile our source code, we need to have the <code>felix.jar</code> file (found in Felix' <code>bin</code> directory) and the <code>example2.jar</code> file in our class path.
We compile the source file using a command like:</p>
</div>
<div class="literalblock">
<div class="content">
<pre>javac -d c:\classes *.java</pre>
</div>
</div>
<div class="paragraph">
<p>This command compiles all source files and outputs the generated classes into a subdirectory of the <code>c:\classes</code> directory;
this subdirectory is <code>tutorial\example4</code>, named after the package we specified in the source file.
For the above command to work, the <code>c:\classes</code> directory must exist.
After compiling, we need to create a JAR file containing the generated package directories.
We will also add our manifest file that contains the bundle&#8217;s meta-data to the JAR file.
To create the JAR file, we issue the command:</p>
</div>
<div class="literalblock">
<div class="content">
<pre>jar cfm example4.jar manifest.mf -C c:\classes tutorial\example4</pre>
</div>
</div>
<div class="paragraph">
<p>This command creates a JAR file using the manifest file we created and includes all of the classes in the <code>tutorial\example4</code> directory inside of the <code>c:\classes</code> directory.
Once the JAR file is created, we are ready to install and start the bundle.</p>
</div>
<div class="paragraph">
<p>To run Felix, we follow the instructions described in usage.html.
When we start Felix, it asks for a profile name, we will put all of our bundles in a profile named <code>tutorial</code>.
After running Felix, we should check that all tutorial bundles are stopped, except for the English dictionary service bundle from Example 2.
We can use the Felix <code>lb</code> shell command to get a list of all bundles, their state, and their bundle identifier number.
If the Example 2 bundle is not active, we should start the bundle using the <code>start</code> command along with the bundle&#8217;s identifier number displayed by the <code>lb</code> command and stop any other unneeded tutorial bundles using the stop command.
(Note: Felix uses some bundles to provide its command shell, so do not stop these bundles.) Now we can install and start our dictionary client bundle.
Assuming that we created our bundle in the directory <code>c:\tutorial</code>, we can install and start it in Felix' shell using the following command:</p>
</div>
<div class="literalblock">
<div class="content">
<pre>start file:/c:/tutorial/example4.jar</pre>
</div>
</div>
<div class="paragraph">
<p>The above command installs and starts the bundle in a single step;
it is also possible to install and start the bundle in two steps by using the Felix <code>install</code> and <code>start</code> shell commands.
When we start the bundle, it will use the shell thread to prompt us for words.
Enter one word at a time to check the words and enter a blank line to stop checking words.
To restart the bundle, we must use the Felix shell <code>lb</code> command to get the bundle identifier number for the bundle and first use the <code>stop</code> command to stop the bundle, then the <code>start</code> command to restart it.
To test the dictionary service, enter any of the words in the dictionary (e.g., "welcome", "to", "the", "OSGi", "tutorial") or any word not in the dictionary.</p>
</div>
<div class="paragraph">
<p>Since this client monitors the dynamic availability of the dictionary service, it is robust in the face of sudden departures of the the dictionary service.
Further, when a dictionary service arrives, it automatically gets the service if it needs it and continues to function.
These capabilities are a little difficult to demonstrate since we are using a simple single-threaded approach, but in a multi-threaded or GUI-oriented application this robustness is very useful.</p>
</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>