Example 7 - Spell Checker Client Bundle :: Apache Felix Home Subprojects Dependency Manager Event Admin File Install Framework Gogo Shell Health Checks Inventory Log Logback Maven bundle plugin Maven SCR plugin Metatype Service Preferences Service Remote Shell Script console plugin Lightweight shell Shell TUI Web Console Downloads Documentation Documentation Downloads Getting Started News Community Apache Felix Project Info Contributing Projects Using Felix Development Coding Standards DEPENDENCIES file template Provisional OSGi API Policy Release Management Site How To Using the OSGi Compliance Tests FAQS Apache Felix Bundle Plugin Frequently Asked Questions Apache Felix SCR Plugin Frequently Asked Questions Subprojects Apache Felix Dependency Manager Guides Apache Felix Dependency Manager - Migrating from earlier versions Dependency Manager - Annotations Dependency Manager - Background Dependency Manager - Bundles and Dependencies Dependency Manager - Design Patterns Dependency Manager - Development Dependency Manager - History Dependency Manager - JavaDocs Dependency Manager - Migrating from other solutions. Dependency Manager - Performance Tuning Dependency Manager - Resource adapters Dependency Manager - What’s new in version 4? Dependency Manager Lambda What’s New in R15 Reference Dependency Manager - Adapter Dependency Manager - Aspect Dependency Manager - Bundle Adapter Dependency Manager - Bundle Dependency Dependency Manager - Components Dependency Manager - Configuration Dependency Dependency Manager - Dependencies Dependency Manager - External Links Dependency Manager - Factory Configuration Adapter Service Dependency Manager - Resource Adapter Dependency Manager - Resource Dependency Dependency Manager - Service Dependency Dependency Manager - Service Scopes Dependency Manager - Singleton Component Dependency Manager - Thread Model Dependency Manager Annotations Tutorials Dependency Manager - Annotations Dependency Manager - Getting Started Dependency Manager - Leveraging the shell Dependency Manager sample projects Apache Felix Event Admin Apache Felix File Install Apache Felix Framework Apache Felix Framework Bundle Cache Apache Felix Framework Configuration Properties Apache Felix Framework Frequently Asked Questions Apache Felix Framework Launching and Embedding Apache Felix Framework Usage Documentation Apache Felix Framework Security Apache Felix Gogo RFC 147 Overview Apache Felix Health Checks Apache Felix Inventory Printer Apache Felix Log Apache Felix Logback Apache Felix Maven Bundle Plugin (BND) Apache Felix Metatype Service Apache Felix OSGi Bundle Repository (OBR) Apache Felix Preferences Service Apache Felix Remote Shell Apache Felix Shell Apache Felix Shell TUI Apache Felix Web Console Extending the Apache Felix Web Console Web Console RESTful API Web Console Security Provider Extensions Branding the Web Console Providing Resources Providing Web Console Plugins Web Console Logging Web Console Output Templating Tutorials Apache Felix Application Demonstration Apache Felix OSGi Tutorial OSGi Frequently Asked Questions OSGI Tutorial Apache Felix Tutorial Example 1 - Service Event Listener Bundle Apache Felix Tutorial Example 2 Apache Felix Tutorial Example 2b Apache Felix Tutorial Example 3 Apache Felix Tutorial Example 4 Apache Felix Tutorial Example 5 Example 6 - Spell Checker Service Bundle Example 7 - Spell Checker Client Bundle Example 8 - Spell Checker Service using Service Binder Example 9 - Spell Checker Service using Declarative Services Apache License 2.0 Site map Documentation master Documentation master Documentation Tutorials OSGI Tutorial Example 7 - Spell Checker Client Bundle Edit this Page Example 7 - Spell Checker Client Bundle In this example we create a client for the spell checker service we implemented in Example 6. This client monitors the dynamic availability of the spell checker service using the Service Tracker and is very similar in structure to the dictionary client we implemented in Example 5. The functionality of the spell checker client reads passages from standard input and spell checks them using the spell checker service. Our bundle uses its bundle context to create a ServiceTracker object to monitor spell checker services. The source code for our bundle is as follows in a file called Activator.java: /* * Apache Felix OSGi tutorial. **/ package tutorial.example7; 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.util.tracker.ServiceTracker; import tutorial.example6.service.SpellChecker; /** * This class implements a bundle that uses a spell checker * service to check the spelling of a passage. This bundle * is essentially identical to Example 5, in that it uses the * Service Tracker to monitor the dynamic availability of the * spell checker service. When starting this bundle, the thread * calling the start() method is used to read passages from * standard input. You can stop spell checking passages by * entering an empty line, but to start spell checking again * you must stop and then restart the bundle. **/ public class Activator implements BundleActivator { // Bundle's context. private BundleContext m_context = null; // The service tacker object. private ServiceTracker m_tracker = null; /** * Implements BundleActivator.start(). Creates a Service * Tracker object to monitor spell checker services. Enters * a spell check loop where it reads passages from standard * input and checks their spelling using the spell checker service. * (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; // Create a service tracker to monitor dictionary services. m_tracker = new ServiceTracker( m_context, m_context.createFilter( "(objectClass=" + SpellChecker.class.getName() + ")"), null); m_tracker.open(); try { System.out.println("Enter a blank line to exit."); String passage = ""; BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); // Loop endlessly. while (true) { // Ask the user to enter a passage. System.out.print("Enter passage: "); passage = in.readLine(); // Get the selected dictionary service, if available. SpellChecker checker = (SpellChecker) m_tracker.getService(); // If the user entered a blank line, then // exit the loop. if (passage.length() == 0) { break; } // If there is no spell checker, then say so. else if (checker == null) { System.out.println("No spell checker available."); } // Otherwise check passage and print misspelled words. else { String[] errors = checker.check(passage); if (errors == null) { System.out.println("Passage is correct."); } else { System.out.println("Incorrect word(s):"); for (int i = 0; i < errors.length; i++) { System.out.println(" " + errors[i]); } } } } } 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) { } } The client uses the Service Tracker to listen for spell checker services. Like normal, we must create a manifest.mf file that contains the meta-data for our bundle; the manifest file contains the following: Bundle-Name: Spell checker client Bundle-Description: A bundle that uses the spell checker service Bundle-Vendor: Richard Hall Bundle-Version: 1.0.0 Bundle-Activator: tutorial.example7.Activator Import-Package: org.osgi.framework, org.osgi.util.tracker, tutorial.example6.service We specify which class is used to activate the bundle via the Bundle-Activator attribute and also specify that our bundle imports the OSGi core, OSGi Service Tracker, and spell checker service interface packages with the Import-Package 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.) To compile our source code, we need to have the felix.jar file (found in Felix' bin directory) and the example6.jar file in our class path. We compile the source file using a command like: javac -d c:\classes *.java This command compiles all source files and outputs the generated classes into a subdirectory of the c:\classes directory; this subdirectory is tutorial\example7, named after the package we specified in the source file. For the above command to work, the c:\classes 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’s meta-data to the JAR file. To create the JAR file, we issue the command: jar cfm example7.jar manifest.mf -C c:\classes tutorial\example7 This command creates a JAR file using the manifest file we created and includes all of the classes in the tutorial\example6 directory inside of the c:\classes directory. Once the JAR file is created, we are ready to install and start the bundle. 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 tutorial. After running Felix, we should stop all tutorial bundles except for the service bundles. Use the lb command to make sure that only the bundles from Example 2, Example 2b, and Example 6 are active; use the start and stop 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 client bundle. Assuming that we created our bundle in the directory c:\tutorial, we can install and start it in Felix' shell using the following command: start file:/c:/tutorial/example7.jar 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 install and start shell commands. When we start the bundle, it will use the shell thread to prompt us for passages; a passage is a collection or words separate by spaces, commas, periods, exclamation points, question marks, colons, or semi-colons. Enter a passage and press the enter key to spell check the passage or enter a blank line to stop spell checking passages. To restart the bundle, we must use the Felix shell lb command to get the bundle identifier number for the bundle and first use the stop command to stop the bundle, then the start command to restart it. Since this client uses the Service Tracker to monitor the dynamic availability of the spell checker service, it is robust in the scenario where the spell checker service suddenly departs. Further, when a spell checker 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. Content licensed under AL2. UI licensed under MPL-2.0 with extensions licensed under AL2