Difference between revisions of "OSGi : Develop Simple Apps"
Line 255: | Line 255: | ||
3. If the service reference is valid, invoke its services and <b>release the service object</b> referenced by the specified ''ServiceReference'' object. | 3. If the service reference is valid, invoke its services and <b>release the service object</b> referenced by the specified ''ServiceReference'' object. | ||
− | if (finderService != null) { | + | <source lang="java"> |
+ | if (finderService != null) { | ||
// invoke the services | // invoke the services | ||
− | + | context.ungetService(reference); | |
} | } | ||
+ | </source> |
Revision as of 23:05, 22 January 2011
Main Page · Course Description · Course Topics · Schedule, Students, Teams · Course Resources · Course Projects
OSGi Activities
- Start and run the Eclipse for OSGi as installed in the previous lecture.
- Open the Subversion Perspective in Eclipse for OSGi.
- Check out the Simple Sample from OSGi Course Repository
- Run the sample and change it.
- Define the main steps involved in developing OSGi applications.
- Write a small tutorial (main steps) about using Eclipse to develop OSGi applications.
Start the lab activities in the order defined below:
- Check out the Service Interface
- Check out the Service Provider
- Check out the Service Consumer
Steps for Building Bundels
1. Study the Interfaces
2. Define the Bundle Service Interface
2.1 Define the Java Interface that exposes the services
Let us suppose that one wants to define a service that allows the user to find a book using its isbn.
package cs.ecl.osgi.simple.bookfinder;
public interface BookFinder {
Book findBook(int isbn) throws BookNotFoundException;
}
Define in the same bundle the classes that you need such as: Book and BookNotFoundException
package cs.ecl.osgi.simple.bookfinder;
public class Book {
private int isbn;
private String title;
public Book(int isbn, String title) {
super();
this.isbn = isbn;
this.title = title;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getIsbn() {
return isbn;
}
public void setIsbn(int isbn) {
this.isbn = isbn;
}
}
package cs.ecl.osgi.simple.bookfinder;
public class BookNotFoundException extends Exception {
private static final long serialVersionUID = -6184839510952070091L;
public BookNotFoundException() {
super();
}
public BookNotFoundException(String arg0) {
super(arg0);
}
}
2.2 Define the MANIFEST.MF for the bundle cs.ecl.osgi.simple.bookfinder
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Bookfinder
Bundle-SymbolicName: cs.ecl.osgi.simple.bookfinder
Bundle-Version: 1.0.0.qualifier
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-Vendor: Seneca College - Eclipse Course
Export-Package: cs.ecl.osgi.simple.bookfinder
3. Define the Bundle Service Provider
The service bookfinder could be used only if there is a bundle that implements the service. The bundle cs.ecl.osgi.simple.bookfinderservice implements BundleActivator interface in the Activator class. This bundle will be called 'service provider'.
3.1 Define the Activator class for the service provider
package cs.ecl.osgi.simple.bookfinderservice;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import cs.ecl.osgi.simple.bookfinder.BookFinder;
import cs.ecl.osgi.simple.bookfinderservice.internals.BookFinderImplementation;
public class Activator implements BundleActivator {
private static BundleContext context;
static BundleContext getContext() {
return context;
}
public void start(BundleContext bundleContext) throws Exception {
Activator.context = bundleContext;
BookFinder bookService = new BookFinderImplementation();
context.registerService(BookFinder.class.getName(), bookService, null);
System.out.println(" Bookfinder service registered ");
}
public void stop(BundleContext bundleContext) throws Exception {
Activator.context = null;
System.out.println(" Bookfinder service stopped ");
}
}
3.2 Define the implementation class for the service
The class must be defined in an internal package cs.ecl.osgi.simple.bookfinderservice.internals The package will not be exposed to the outside world
package cs.ecl.osgi.simple.bookfinderservice.internals;
import cs.ecl.osgi.simple.bookfinder.Book;
import cs.ecl.osgi.simple.bookfinder.BookFinder;
import cs.ecl.osgi.simple.bookfinder.BookNotFoundException;
public class BookFinderImplementation implements BookFinder {
private static final Book[] BOOKS = new Book[] {
new Book(1234, "Java Programming Language"),
new Book(5678, "OSGi") };
public Book findBook(int isbn) throws BookNotFoundException {
Book found = null;
for (Book b : BOOKS)
if (b.getIsbn() == isbn) {
found = b;
break;
}
if (found == null)
throw new BookNotFoundException("No book with isbn = " + isbn);
return found;
}
}
//This is a simple and trivial implementation.
//There real implementation should use database, distributed system, etc.
3.3 Define the MANIFEST.MF for the cs.ecl.osgi.simple.bookfinderservice bundle
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Bookfinderservice
Bundle-SymbolicName: cs.ecl.osgi.simple.bookfinderservice
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: cs.ecl.osgi.simple.bookfinderservice.Activator
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Import-Package: org.osgi.framework;version="1.3.0"
Bundle-Vendor: Seneca College - Eclipse Course
Export-Package: cs.ecl.osgi.simple.bookfinderservice
Require-Bundle: cs.ecl.osgi.simple.bookfinder;bundle-version="1.0.0"
The bundle export only the package cs.ecl.osgi.simple.bookfinderservice Meanwhile, the implementation package - cs.ecl.osgi.simple.bookfinderservice.internals - is hidden to the outside world and can be changed dynamically any time a better implementation is created.
The bundle provider requires the osgi framework and the interface bundle (e.g. cs.ecl.osgi.simple.bookfinder bundle)
- Require-Bundle: cs.ecl.osgi.simple.bookfinder;bundle-version="1.0.0"
- Import-Package: org.osgi.framework;version="1.3.0"
The bundle cs.ecl.osgi.simple.bookfinderservice export its service, namely the bood finder service:
- Export-Package: cs.ecl.osgi.simple.bookfinderservice
3. Define the Bundle Service Consumer
The service bookfinder could be used only if there is a bundle that requests its service. The bundle cs.ecl.osgi.simple.bookfindconsumer by the time is activated BundleActivator looks for the service in the registry. This bundle will be called 'service consumer'.
3.1 Define the Activator class for the service consumer
package cs.ecl.osgi.simple.bookfinderconsumer.bookfinderconsumer;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import cs.ecl.osgi.simple.bookfinder.BookFinder;
import cs.ecl.osgi.simple.bookfinder.BookNotFoundException;
public class Activator implements BundleActivator {
private static BundleContext context;
private BookFinder finderService;
static BundleContext getContext() {
return context;
}
public void start(BundleContext bundleContext) throws Exception {
Activator.context = bundleContext;
ServiceReference reference = context
.getServiceReference(BookFinder.class.getName());
if (reference != null) {
finderService = (BookFinder) context.getService(reference);
if (finderService != null) {
printBook(finderService);
context.ungetService(reference);
} else
System.err.println("the service cannot be used !!!");
} else
System.err.println("the service cannot be found !!!");
}
public void stop(BundleContext bundleContext) throws Exception {
Activator.context = null;
System.err.println("consumer bundle stopped");
}
public void printBook(BookFinder finderService) {
try {
String s = finderService.findBook(1234).getTitle();
System.out.print("Book found: " + s + " !!!");
} catch (BookNotFoundException ex) {
System.err.println(ex.getMessage());
}
}
}
Steps to find and use the service:
1. Look for the service reference in the bundle context:
The Framework returns ServiceReference objects from the BundleContext.getServiceReference method. A ServiceReference object may be shared between bundles and can be used: 1. to examine the properties of the service 2. to get the service object.
ServiceReference reference = context.getServiceReference(BookFinder.class.getName());
2. Look for the service object referenced by the specified ServiceReference object, namely the reference variable obtained at the first step.
if (reference != null) finderService = (BookFinder) context.getService(reference);
3. If the service reference is valid, invoke its services and release the service object referenced by the specified ServiceReference object.
if (finderService != null) {
// invoke the services
context.ungetService(reference);
}