Difference between revisions of "Opentaps OSGI Proof Of Concept Tutorial"

From Opentaps Wiki
Jump to navigationJump to search
Line 23: Line 23:
 
  /* ServiceTracker */ userAdminTrckr = new ServiceTracker(context, UserAdmin.class.getName(), null);
 
  /* ServiceTracker */ userAdminTrckr = new ServiceTracker(context, UserAdmin.class.getName(), null);
 
         userAdminTrckr.open();
 
         userAdminTrckr.open();
 +
 +
One interesting example for an Activator is the one from <tt>org.opentaps.bundle.webshell</tt>.  This Activator is responsible for loading the <tt>Controller</tt> class into the osgi <tt>HttpService</tt>. Because the web shell Activator does not know when <tt>HttpService</tt> would be started, a <tt>ServiceTracker</tt> for <tt>HttpService</tt> is used to register the <tt>Controller</tt> class. So, inside the start method, we open the ServiceTracker:
 +
        httpServiceTracker = new HttpServiceTracker(context, controller);
 +
        httpServiceTracker.open();
 +
 +
This <tt>ServiceTracker</tt> is registered to <tt>HttpService</tt> in its constructor:
 +
        public HttpServiceTracker(BundleContext context, Controller controller) {
 +
            super(context, HttpService.class.getName(), null);
 +
            this.controller = controller;
 +
        }
 +
 +
And then, the <tt>addingService</tt> method is over-ridden to register the <tt>Controller</tt>:
 +
        @Override
 +
        public Object addingService(ServiceReference reference) {
 +
    HttpService service = (HttpService) context.getService(reference);
 +
            if (service != null) {
 +
                try {
 +
                    service.registerServlet(controller.getRoot(), controller, null, new AuthHttpContext(service.createDefaultHttpContext()));
 +
        //...

Revision as of 18:11, 7 April 2010

war/pom.xml defines the bundles which are used, including both remote bundles

     <dependency>
         <groupId>javax.servlet</groupId>
         <artifactId>com.springsource.javax.servlet</artifactId>
     </dependency>

and our bundles:

   <dependency>
   	<groupId>org.opentaps</groupId>
   	<artifactId>org.opentaps.core.persistence</artifactId>
   	<version>0.0.1-SNAPSHOT</version>
   	<scope>provided</scope>
   </dependency>

Each bundle in turn contains its own pom.xml which defines itself, its version, its build process (using Maven), and its dependencies.

The pom.xml defines an Activator class to manage the bundle:

   <Bundle-Activator>org.opentaps.core.persistence.Activator</Bundle-Activator>

This class has the start(BundleContext context) and stop(BundleContext context) methods which controls what happens when the bundle is started and stopped. The important things it does are:

  • Register services, which binds implementation to interfaces. For example, we can bind org.opentaps.core.security.useradmin.internal.UserAdminImpl to org.osgi.service.useradmin.UserAdmin
context.registerService(UserAdmin.class.getName(), new UserAdminImpl(), null);
  • Open a ServiceTracker for to watch a service's lifecycle. We cannot guarantee the loading order of bundles by osgi, so the service tracker helps to perform necessary actions when services are added, removed, or modified, independent of the loading details. For example,
/* ServiceTracker */ userAdminTrckr = new ServiceTracker(context, UserAdmin.class.getName(), null);
       userAdminTrckr.open();

One interesting example for an Activator is the one from org.opentaps.bundle.webshell. This Activator is responsible for loading the Controller class into the osgi HttpService. Because the web shell Activator does not know when HttpService would be started, a ServiceTracker for HttpService is used to register the Controller class. So, inside the start method, we open the ServiceTracker:

       httpServiceTracker = new HttpServiceTracker(context, controller);
       httpServiceTracker.open();

This ServiceTracker is registered to HttpService in its constructor:

       public HttpServiceTracker(BundleContext context, Controller controller) {
           super(context, HttpService.class.getName(), null);
           this.controller = controller;
       }

And then, the addingService method is over-ridden to register the Controller:

       @Override
       public Object addingService(ServiceReference reference) {
   HttpService service = (HttpService) context.getService(reference);
           if (service != null) {
               try {
                   service.registerServlet(controller.getRoot(), controller, null, new AuthHttpContext(service.createDefaultHttpContext()));
       //...