blob: 43eada71e3964f48cdd641d32265bad8cc700797 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Example 6 - Spell Checker Service Bundle :: Apache Felix</title>
<link rel="canonical" href="https://felix.apache.org/documentation/tutorials-examples-and-presentations/apache-felix-osgi-tutorial/apache-felix-tutorial-example-6.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" 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 is-current-page" 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-6.html">Example 6 - Spell Checker Service Bundle</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-6.adoc">Edit this Page</a></div>
</div>
<div class="content">
<article class="doc">
<h1 class="page">Example 6 - Spell Checker Service Bundle</h1>
<div class="paragraph">
<p><em>(This example should be rewritten to use the Service Tracker.)</em></p>
</div>
<div class="paragraph">
<p>In this example, we complicate things further by defining a new service that uses an arbitrary number of dictionary services to perform its function.
More precisely, we define a spell checker service will aggregate all dictionary services and provide another service that allows us to spell check passages using our underlying dictionary services to verify the spelling of words.
Our bundle will only provide the spell checker service if there is at least one dictionary service available.
First, we will start by defining the spell checker service interface in a file called <code>SpellChecker.java</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>/*
* Apache Felix OSGi tutorial.
**/
package tutorial.example6.service;
/**
* A simple service interface that defines a spell checker service.
* A spell checker service checks the spelling of all words in a
* given passage. A passage is any number of words separated by
* a space character and the following punctuation marks: comma,
* period, exclamation mark, question mark, semi-colon, and colon.
**/
public interface SpellChecker
{
/**
* Checks a given passage for spelling errors. A passage is any
* number of words separated by a space and any of the following
* punctuation marks: comma (,), period (.), exclamation mark (!),
* question mark (?), semi-colon (;), and colon(:).
* @param passage the passage to spell check.
* @return An array of misspelled words or null if no
* words are misspelled.
**/
public String[] check(String passage);
}</pre>
</div>
</div>
<div class="paragraph">
<p>The service interface is quite simple, with only one method that needs to be implemented.
Notice that we put the service interface in the package <code>tutorial.example6.service</code>, instead of just putting it in <code>tutorial.example6</code>.
We did this because we need to share the interface definition with other bundles, therefore it is better to separate service interfaces that need to be shared from code that does not need to be shared.
Such an approach ensures a strong separation between interface and implementation.</p>
</div>
<div class="paragraph">
<p>In the following bundle source code, the bundle needs to create a complete list of all dictionary services;
this is somewhat tricky and must be done carefully.
First, the bundle uses its bundle context to register itself as a service event listener, then it queries for all currently available dictionary services.
After creating the list of dictionary services, the bundle then registers its spell checker service if and only if there is at least one dictionary service available.
These actions must be performed in a synchronized block to avoid interference from service events.
Additionally, since the bundle is monitoring the dynamic availability of the dictionary services, when the number of dictionary services falls to zero or increases from zero, the bundle must unregister and register its spell checker service, respectively.
We implement our bundle in a file called <code>Activator.java</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>/*
* Apache Felix OSGi tutorial.
**/
package tutorial.example6;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.StringTokenizer;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceEvent;
import tutorial.example2.service.DictionaryService;
import tutorial.example6.service.SpellChecker;
/**
* This class implements a bundle that implements a spell
* checker service. The spell checker service uses all available
* dictionary services to check for the existence of words in
* a given sentence. This bundle not only monitors the dynamic
* availability of dictionary services, but it manages the
* aggregation of all available dictionary services as they
* arrive and depart. The spell checker service is only registered
* if there are dictionary services available, thus the spell
* checker service will appear and disappear as dictionary
* services appear and disappear, respectively.
**/
public class Activator implements BundleActivator, ServiceListener
{
// Bundle's context.
private BundleContext m_context = null;
// List of available dictionary service references.
private ArrayList m_refList = new ArrayList();
// Maps service references to service objects.
private HashMap m_refToObjMap = new HashMap();
// The spell checker service registration.
private ServiceRegistration m_reg = null;
/**
* Implements BundleActivator.start(). Adds itself
* as a service listener and queries for all currently
* available dictionary services. Any available dictionary
* services are added to the service reference list. If
* dictionary services are found, then the spell checker
* service is registered.
* @param context the framework context for the bundle.
**/
public void start(BundleContext context) throws Exception
{
m_context = context;
synchronized (m_refList)
{
// Listen for events pertaining to dictionary services.
m_context.addServiceListener(this,
"(&amp;(objectClass=" + DictionaryService.class.getName() + ")" +
"(Language=*))");
// Query for all dictionary services.
ServiceReference[] refs = m_context.getServiceReferences(
DictionaryService.class.getName(), "(Language=*)");
// Add any dictionaries to the service reference list.
if (refs != null)
{
for (int i = 0; i &lt; refs.length; i++)
{
// Get the service object.
Object service = m_context.getService(refs[i]);
// Make that the service is not being duplicated.
if ((service != null) &amp;&amp;
(m_refToObjMap.get(refs[i]) == null))
{
// Add to the reference list.
m_refList.add(refs[i]);
// Map reference to service object for easy look up.
m_refToObjMap.put(refs[i], service);
}
}
// Register spell checker service if there are any
// dictionary services.
if (m_refList.size() &gt; 0)
{
m_reg = m_context.registerService(
SpellChecker.class.getName(),
new SpellCheckerImpl(), null);
}
}
}
}
/**
* Implements BundleActivator.stop(). Does nothing since
* the framework will automatically unregister any registered services,
* release any used services, and remove any event listeners.
* @param context the framework context for the bundle.
**/
public void stop(BundleContext context)
{
// NOTE: The services automatically released.
}
/**
* Implements ServiceListener.serviceChanged(). Monitors
* the arrival and departure of dictionary services, adding and
* removing them from the service reference list, respectively.
* In the case where no more dictionary services are available,
* the spell checker service is unregistered. As soon as any dictionary
* service becomes available, the spell checker service is
* reregistered.
* @param event the fired service event.
**/
public void serviceChanged(ServiceEvent event)
{
synchronized (m_refList)
{
// Add the new dictionary service to the service list.
if (event.getType() == ServiceEvent.REGISTERED)
{
// Get the service object.
Object service = m_context.getService(event.getServiceReference());
// Make that the service is not being duplicated.
if ((service != null) &amp;&amp;
(m_refToObjMap.get(event.getServiceReference()) == null))
{
// Add to the reference list.
m_refList.add(event.getServiceReference());
// Map reference to service object for easy look up.
m_refToObjMap.put(event.getServiceReference(), service);
// Register spell checker service if necessary.
if (m_reg == null)
{
m_reg = m_context.registerService(
SpellChecker.class.getName(),
new SpellCheckerImpl(), null);
}
}
else if (service != null)
{
m_context.ungetService(event.getServiceReference());
}
}
// Remove the departing service from the service list.
else if (event.getType() == ServiceEvent.UNREGISTERING)
{
// Make sure the service is in the list.
if (m_refToObjMap.get(event.getServiceReference()) != null)
{
// Unget the service object.
m_context.ungetService(event.getServiceReference());
// Remove service reference.
m_refList.remove(event.getServiceReference());
// Remove service reference from map.
m_refToObjMap.remove(event.getServiceReference());
// If there are no more dictionary services,
// then unregister spell checker service.
if (m_refList.size() == 0)
{
m_reg.unregister();
m_reg = null;
}
}
}
}
}
/**
* A private inner class that implements a spell checker service;
* see SpellChecker for details of the service.
**/
private class SpellCheckerImpl implements SpellChecker
{
/**
* Implements SpellChecker.check(). Checks the
* given passage for misspelled words.
* @param passage the passage to spell check.
* @return An array of misspelled words or null if no
* words are misspelled.
**/
public String[] check(String passage)
{
// No misspelled words for an empty string.
if ((passage == null) || (passage.length() == 0))
{
return null;
}
ArrayList errorList = new ArrayList();
// Tokenize the passage using spaces and punctionation.
StringTokenizer st = new StringTokenizer(passage, " ,.!?;:");
// Lock the service list.
synchronized (m_refList)
{
// Loop through each word in the passage.
while (st.hasMoreTokens())
{
String word = st.nextToken();
boolean correct = false;
// Check each available dictionary for the current word.
for (int i = 0; (!correct) &amp;&amp; (i &lt; m_refList.size()); i++)
{
DictionaryService dictionary =
(DictionaryService) m_refToObjMap.get(m_refList.get(i));
if (dictionary.checkWord(word))
{
correct = true;
}
}
// If the word is not correct, then add it
// to the incorrect word list.
if (!correct)
{
errorList.add(word);
}
}
}
// Return null if no words are incorrect.
if (errorList.size() == 0)
{
return null;
}
// Return the array of incorrect words.
return (String[]) errorList.toArray(new String[errorList.size()]);
}
}
}</pre>
</div>
</div>
<div class="paragraph">
<p>Note that we do not need to unregister the service in stop() method, because the OSGi framework will automatically do so for us.
The spell checker service that we have implemented is very simple;
it simply parses a given passage into words and then loops through all available dictionary services for each word until it determines that the word is correct.
Any incorrect words are added to an error list that will be returned to the caller.
This solution is not optimal and is only intended for educational purposes.
Next, we 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: Spell checker service
Bundle-Description: A bundle that implements a simple spell checker service
Bundle-Vendor: Richard Hall
Bundle-Version: 1.0.0
Bundle-Activator: tutorial.example6.Activator
Export-Package: tutorial.example6.service
Import-Package: org.osgi.framework,
tutorial.example2.service</pre>
</div>
</div>
<div class="paragraph">
<p>We specify which class used to activate the bundle via the <code>Bundle-Activator</code> attribute.
Our bundle exports the spell checker service interface using the <code>Export-Package</code> attribute and imports the OSGi core framework and dictionary service interface packages using the <code>Import-Package</code> attribute.
(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, we need to have the <code>felix.jar</code> file (found in Felix' <code>bin</code> directory) and the example2.jar 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\example6</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 example6.jar manifest.mf -C c:\classes tutorial\example6</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\example6</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 stop all tutorial bundles except for the service bundles.
Use the <code>lb</code> command to make sure that only the bundles from Example 2 and Example 2b are active;
use the <code>start</code> and <code>stop</code> commands as appropriate to start and stop the various tutorial bundles, respectively.
(Note: Felix uses some bundles to provide its command shell, so do not stop these bundles.) Now we can install and start our spell checker service 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/example6.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.
To stop the bundle, use the Felix <code>stop</code> shell command.
Using the Felix shell <code>lb</code> command to get the bundle identifier number for our spell checker service bundle and we can stop and restart it at will using the <code>stop</code> and <code>start</code> commands, respectively.
Using the <code>services</code> command, we can see which services are currently available in the OSGi framework, including our dictionary and spell checker services.
We can experiment with our spell checker service&#8217;s dynamic availability by stopping the dictionary service bundles;
when both dictionary services are stopped, the <code>services</code> command will reveal that our bundle is no longer offering its spell checker service.
Likewise, when the dictionary services comeback, so will our spell checker service.
We create a client for our spell checker service in Example 7.
To exit Felix, we use the <code>shutdown</code> command.</p>
</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>