zoukankan      html  css  js  c++  java
  • 使用NetBeans6开发OSGi应用(2)——SecondOSGi[88250原创]

    转载请保留作者信息:

    作者:88250

    Bloghttp:/blog.csdn.net/DL88250

    MSN & Gmail & QQDL88250@gmail.com


    摘要

    上一次,我们了解了OSGi的背景并使用NetBeans6,基于Knopflerfish(OSGi的一个RI) 完成了第一个OSGi应用——FirstOSGi。这一次,我们将对OSGi进行深入一点学习——SecondOSGi,让我们掌握Bundles之间的调用!

    准备

    上一次 :-)

    开工:

    1. 创建工程

    打开NetBeans6 IDE,创建两个普通的Java App——SecondOSGi、SecondOSGiClient。把KF下的Sources拷贝到两个工程下(记得加入asm3.0的Jar):

            

    在SecondOSGiClient工程的demo包下的两个Java文件(Demo.java, DemoFactory.java)与SecondOSGi工程demo包下的完全一样,这里是懒得发布编译好的class byte file给Client了,直接给的接口源文件。

    2. 编写manifest.mf

    把工程View切换到Files,改写manifest.mf如下:





    关于manifest.mf里各种properties就不罗嗦了,有很多文档可以参考 :-)

    3. 编写Activator

    下面逐一给出源文件,一一对应上面工程结构图。

    service提供者,即SecondOSGi工程下的:

    /*
     * @(#)Demo.java
     * 
     * This program is free software; you can redistribute it and/or modify
     * it under the terms of the GNU General Public License as published by
     * the Free Software Foundation; either version 3 of the License, or
     * (at your option) any later version.
     * 
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU Library General Public License for more details.
     * 
     * You should have received a copy of the GNU General Public License
     * along with this program; if not, write to the Free Software
     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
     
    */
    package secondosgi.service.demo;


    /**
     * A simple demo service.
     * 
    @author 88250
     * 
    @version 1.0.0.0, Feb 14, 2008
     
    */
    public interface Demo {

        
    /**
         * Add two integers and return the result.
         * 
    @param a
         * 
    @param b
         * 
    @return 
         
    */
        
    public int add(int a, int b);
    }

    /*
     * @(#)DemoFactory.java
     * 
     * This program is free software; you can redistribute it and/or modify
     * it under the terms of the GNU General Public License as published by
     * the Free Software Foundation; either version 3 of the License, or
     * (at your option) any later version.
     * 
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU Library General Public License for more details.
     * 
     * You should have received a copy of the GNU General Public License
     * along with this program; if not, write to the Free Software
     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
     
    */
    package secondosgi.service.demo;

    /**
     * <b>Another</b> very simple demo service API.
     * <p>
     * The intentions of this interface class is to show that different bundles
     * will get different instances of a service, by the means of a 
     * ServiceFactory.
     * </p>
     * 
    @author 88250
     * 
    @version 1.0.0.0, Feb 14, 2008
     
    */
    public interface DemoFactory {

        
    /**
         * Say hello.
         
    */
        
    void hello();
    }

    /*
     * @(#)DemoImpl.java
     * 
     * This program is free software; you can redistribute it and/or modify
     * it under the terms of the GNU General Public License as published by
     * the Free Software Foundation; either version 3 of the License, or
     * (at your option) any later version.
     * 
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU Library General Public License for more details.
     * 
     * You should have received a copy of the GNU General Public License
     * along with this program; if not, write to the Free Software
     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
     
    */
    package secondosgi.service.demo.impl;

    import secondosgi.service.demo.Demo;

    /**
     * Implementation of the Demo service.
     * 
    @author 88250
     * 
    @version 1.0.0.0, Feb 14, 2008
     
    */
    public class DemoImpl implements Demo {

        
    public int add(int a, int b) {
            
    return a + b;
        }
    }

    /*
     * @(#)DemoFactoryImpl.java
     * 
     * This program is free software; you can redistribute it and/or modify
     * it under the terms of the GNU General Public License as published by
     * the Free Software Foundation; either version 3 of the License, or
     * (at your option) any later version.
     * 
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU Library General Public License for more details.
     * 
     * You should have received a copy of the GNU General Public License
     * along with this program; if not, write to the Free Software
     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
     
    */
    package secondosgi.service.demo.impl;

    import secondosgi.service.demo.DemoFactory;
    import org.osgi.framework.Bundle;

    /**
     * Implementation of the DemoFactory service. The intentions of this
     * class is to show that different bundles will get different instances
     * of a service, by the means of a ServiceFactory.
     * 
    @author 88250
     * 
    @version 1.0.0.0, Feb 14, 2008
     
    */
    public class DemoFactoryImpl implements DemoFactory {

        
    private Bundle b;

        
    /**
         * Constructor with argument.
         * 
    @param b a <code>Bundle</code> 
         
    */
        
    public DemoFactoryImpl(Bundle b) {
            
    this.b = b;
        }

        
    public void hello() {
            System.out.println(
    "Hello bundle #" + b.getBundleId());
        }
    }

    很关键的Activator,实现服务的注册,注销:
    /*
     * @(#)Activator.java
     * 
     * This program is free software; you can redistribute it and/or modify
     * it under the terms of the GNU General Public License as published by
     * the Free Software Foundation; either version 3 of the License, or
     * (at your option) any later version.
     * 
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU Library General Public License for more details.
     * 
     * You should have received a copy of the GNU General Public License
     * along with this program; if not, write to the Free Software
     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
     
    */
    package secondosgi.service.demo.impl;

    import secondosgi.service.demo.Demo;
    import secondosgi.service.demo.DemoFactory;
    import java.util.Hashtable;
    import org.osgi.framework.Bundle;
    import org.osgi.framework.BundleActivator;
    import org.osgi.framework.BundleContext;
    import org.osgi.framework.ServiceFactory;
    import org.osgi.framework.ServiceRegistration;

    /**
     * Activator which creates and registers a Demo1 service.
     * 
    @author 88250
     * 
    @version 1.0.0.0, Feb 14, 2008
     
    */
    public class Activator implements BundleActivator {

        
    private Demo demo;

        
    public void start(BundleContext bc) {
            System.out.println(
    "start " + getClass().getName());
            demo 
    = new DemoImpl();
            bc.registerService(Demo.
    class.getName(),
                    demo,
                    
    new Hashtable());

            
    // Create a service factory for DemoFactory implementations
            ServiceFactory factory = new ServiceFactory() {

                Hashtable services 
    = new Hashtable();
                
    // Will get called when a bundle request a service
                @SuppressWarnings("unchecked")
                
    public Object getService(Bundle b,
                        ServiceRegistration reg) {
                    System.out.println(
    "get from " + b.getBundleId());

                    
    // Create when necessary
                    DemoFactory impl = (DemoFactory) services.get(b);
                    
    if (impl == null) {
                        impl 
    = new DemoFactoryImpl(b);
                        services.put(b, impl);
                    }
                    
    return impl;
                }

                
    // will get called when a bundle ungets a service or stops
                public void ungetService(Bundle b,
                        ServiceRegistration reg,
                        Object service) {
                    System.out.println(
    "unget from " + b.getBundleId());
                    services.remove(b);
                }
            };

            
    // Note how factory only implements ServiceFactory, 
            
    // but we still register as DemoFactory1 service
            bc.registerService(DemoFactory.class.getName(),
                    factory,
                    
    new Hashtable());
        }

        
    public void stop(BundleContext bc) {
            System.out.println(
    "stop " + getClass().getName());

            demo 
    = null;
        }
    }

    client角色,服务使用者,即SecondOSGiClient工程下的(Demo,DemoFactory两个接口同服务提供的)。
    在这个Activator里,我们实现了服务的查找、调用、服务提供者状态的监听:
    /*
     * @(#)Activator.java
     * 
     * This program is free software; you can redistribute it and/or modify
     * it under the terms of the GNU General Public License as published by
     * the Free Software Foundation; either version 3 of the License, or
     * (at your option) any later version.
     * 
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU Library General Public License for more details.
     * 
     * You should have received a copy of the GNU General Public License
     * along with this program; if not, write to the Free Software
     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
     
    */
    package secondosgi.service.client.impl;

    import secondosgi.service.demo.Demo;
    import secondosgi.service.demo.DemoFactory;
    import org.osgi.framework.BundleActivator;
    import org.osgi.framework.BundleContext;
    import org.osgi.framework.ServiceEvent;
    import org.osgi.framework.ServiceListener;
    import org.osgi.framework.ServiceReference;

    /**
     * Activator which registers a listener for, and test, any Demo service.
     * 
    @author 88250
     * 
    @version 1.0.0.0, Feb 14, 2008
     
    */
    public class Activator implements BundleActivator, ServiceListener {

        
    private static BundleContext bc;

        
    private ServiceListener listener;

        
    public void start(BundleContext bc) {
            System.out.println(
    "start " + getClass().getName());
            Activator.bc 
    = bc;

            
    try {
                
    // Filter that matches all Demo services
                String filter = "(objectclass=" + Demo.class.getName() + ")";

                
    // Fetch all registered Demo services
                
    // and test them manually
                ServiceReference[] srl =
                        bc.getServiceReferences(Demo.
    class.getName(), filter);
                
    for (int i = 0; srl != null && i < srl.length; i++) {
                    testService(srl[i]);
                }

                
    // ...and catch all newly registed ones too.
                bc.addServiceListener(listener, filter);
            } 
    catch (Exception e) {
                
    // sounds unlikely, but filter syntax errors are easy to write.
                e.printStackTrace();
            }

            testServiceFactory();
        }

        
    void testServiceFactory() {
            
    // Try to get a reference to the service produced by a factory
            ServiceReference factorySR = bc.getServiceReference(DemoFactory.class.getName());
            
    if (factorySR != null) {
                DemoFactory df 
    = (DemoFactory) bc.getService(factorySR);
                
    if (df != null) {
                    
    // Different bundles will get different printouts
                    df.hello();
                }
            }
        }

        
    void testService(ServiceReference sr) {
            Demo demo 
    = (Demo) bc.getService(sr);
            
    int r = demo.add(1401);

            System.out.println(
    "Testing " + demo + ", result=" + r);

            
    // ..return the object to be nice
            bc.ungetService(sr);
        }

        
    public void stop(BundleContext bc) {
            System.out.println(
    "stop " + getClass().getName());
            Activator.bc 
    = null;
        }

        
    public void serviceChanged(ServiceEvent event) {
            ServiceReference sr 
    = event.getServiceReference();

            
    // just print some info and call testService() on
            
    // all registered Demo services
            switch (event.getType()) {
                
    case ServiceEvent.REGISTERED:
                    System.out.println(
    "Got Demo service");
                    testService(sr);
                    
    break;
                
    case ServiceEvent.UNREGISTERING:
                    System.out.println(
    "Lost Demo service");
                    
    break;
                
    case ServiceEvent.MODIFIED:
                    System.out.println(
    "Modified Demo service");
                    
    break;
                
    default:
                    
    break;
            }
        }
    }

    4. 测试

    打开KF控制中心:

    daniel@daniel-laptop:~/Work/knopflerfish_osgi_2.0.4/knopflerfish.org/osgi$ java -jar framework.jar 


    打开构建好的SecondOSGi.jar以及SecondOSGiClient.jar,运行!



    总结

    这一次,我们对OSGi的了解更深了一步。

    从设计的角度:一个可扩展的Service-Oriented组件服务模型

    从开发的角度:我们发布接口给客户,实现了“针对接口编程”的OO核心实践

    不足之处

    我们一直都是在KF的控制台下启动的应用,如何做成独立的(standalone)可运行的Jar发布呢?

    1. 在命令行下启动OSGi框架

    首先,编写一个启动参数文件:secondosgi.xargs
    -launch
    -istart /home/daniel/Work/Sources/Java/SecondOSGi/dist/SecondOSGi.jar
    -istart /home/daniel/Work/Sources/Java/SecondOSGiClient/dist/SecondOSGiClient.jar

    然后,进入KF的安装目录,启动我们的应用:


    现在,我们只是脱离了KF的图形界面控制中心,在命令行下面启动的KF框架,并把SecondOSGi与SeondOSGiClient安装运行在KF框架里。一切的主动权还是在KF手里。
    结合以前JavaEE的实践,JSP/Servlets,EJBs不都是被控制在容器(container)里的吗?
    不过,话又说回来了,我希望自己的框架应用构建于OSGi之上,而不是之内。
    之内的部分应该是可扩展的Plug-ins部分,让OSGi作为底层框架,为我们提供稳定的插件机制。
    之外的部分应该是我们应用的框架,构建在OSGi之上。对OSGi做一个封装,就KF而言,就是封装它的命令接口,让我们的框架可以对插件随时安装、卸载、运行、停止、更新。。。。
    当然,以上是个设想,学习OSGi第二天的设想。。。。
    总之不足的地方很多,要把这个示例慢慢演化成正真具有价值的应用可能还需要一些时间。

  • 相关阅读:
    part11-1 Python图形界面编程(Python GUI库介绍、Tkinter 组件介绍、布局管理器、事件处理)
    part10-3 Python常见模块(正则表达式)
    Cyclic Nacklace HDU
    模拟题 Right turn SCU
    状态DP Doing Homework HDU
    Dp Milking Time POJ
    区间DP Treats for the Cows POJ
    DP Help Jimmy POJ
    Dales and Hills Gym
    Kids and Prizes Gym
  • 原文地址:https://www.cnblogs.com/lanzhi/p/6470597.html
Copyright © 2011-2022 走看看