使用eclipse开发felix的OSGI插件

别来无恙 提交于 2019-11-29 11:59:05

1、官网下载http://felix.apache.org/downloads.cgi
当前最新版本6.0.3
运行felix窗口有两种方式
(1) 可以直接下载发布版本
Felix Framework Distribution(org.apache.felix.main.distribution-6.0.3.zip

解压后目录

进入项目目录,命令行下执行

java -jar ./bin/felix.jar

felix.jar 默认会在当前运行目录的 bundle 文件夹内加载启动所需的插件jar,config 目录下的 config.propeties 和 system.properties 里面加载环境变量,如果将其他目录作为启动根目录,该目录下不存在 felix 启动所需信息,启动就会有问题。项目第一次启动的时候会在启动目录下创建一个felix-cache的目录,用于存放框架运行过程产生的数据,当然该目录可以在启动的时候配置,使用 java -jar ./bin/felix.jar <felix-dir> 即可。

(2) 源码导入eclipse运行
下载子项目Mainorg.apache.felix.main-6.0.3-project.zip


解压org.apache.felix.main-6.0.3-project.zip,进入目录,命令行下
运行mvn eclipse:eclipse工程文件,
再输入mvn package,打包编译
File->Import导入到eclipse

在eclipse的org.apache.felix.main.Main类右键运行Run As Java Application

常用命令

lb:查看已装插件包
start:运行插件包
stop:停止运行插件包
install:安装插件包
uninstall:删除插件包
其它命令可以通过help查看

2、felix开发插件
参考是felix官方例子代码apache-felix-osgi-tutorial里的
apache-felix-tutorial-example-2
apache-felix-tutorial-example-2b
apache-felix-tutorial-example-3
这是一个检查输入单词(英文、中文....)是否正确的例子功能

先定义一个服务类:

package test.penngo.service;
 
/**
 * 简单的定义了一个字典服务接口,该接口的功能只是简单的验证一个词是否正确。
**/
public interface DictionaryService
{
    /**
            * 检查 单词是否存在
    **/
    public boolean checkWord(String word);
}

英文词典插件包开发

package tutorial.example2;

import java.util.Hashtable;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import test.penngo.service.DictionaryService;

/**
 * 英文字典服务插件
 **/
public class Activator implements BundleActivator {
	/**
	 * 服务启动
	 * 
	 * @param context the framework context for the bundle.
	 **/
	public void start(BundleContext context) {
		Hashtable<String, String> props = new Hashtable<String, String>();
		props.put("Language", "English");
		context.registerService(DictionaryService.class.getName(), new DictionaryImpl(), props);
	}

	/**
	 * 服务停止
	 * 
	 * @param context the framework context for the bundle.
	 **/
	public void stop(BundleContext context) {
		// NOTE: The service is automatically unregistered.
	}

	/**
	 * 英文词典服务实现
	 **/
	private static class DictionaryImpl implements DictionaryService {
		String[] m_dictionary = { "welcome", "to", "the", "osgi", "tutorial" };

		/**
		 * 英文单词检测
		 **/
		public boolean checkWord(String word) {
			word = word.toLowerCase();
			for (int i = 0; i < m_dictionary.length; i++) {
				if (m_dictionary[i].equals(word)) {
					return true;
				}
			}
			return false;
		}
	}
}

META-INF.MF

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: English
Bundle-Name: English dictionary
Bundle-Description: A bundle that registers an English dictionary service
Bundle-Vendor: penngo
Bundle-Version: 1.0.0
Bundle-Activator: tutorial.example2.Activator
Import-Package: org.osgi.framework, test.penngo.service

英文词典插件打包导出,eclipse自带的export打包会有问题,本文使用fatjar工具打包,

中文词典插件包开发

package tutorial.example2b;
 
import java.util.Hashtable;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import test.penngo.service.DictionaryService;

/**
 * 中文词典包
**/
public class Activator implements BundleActivator
{
    public void start(BundleContext context)
    {
        Hashtable<String, String> props = new Hashtable<String, String>();
        props.put("Language", "Chinese");
        context.registerService(
            DictionaryService.class.getName(), new DictionaryImpl(), props);
    }
 
    public void stop(BundleContext context)
    {
        // NOTE: The service is automatically unregistered.
    }
 
    /**
            *  中文词典服务实现
    **/
    private static class DictionaryImpl implements DictionaryService
    {
        // The set of words contained in the dictionary.
        String[] m_dictionary =
            { "欢迎", "你好", "教程", "模块" };
 
        public boolean checkWord(String word)
        {
            word = word.toLowerCase();
            for (int i = 0; i < m_dictionary.length; i++)
            {
                if (m_dictionary[i].equals(word))
                {
                    return true;
                }
            }
            return false;
        }
    }
}
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: Chinese
Bundle-Name: Chinese dictionary
Bundle-Description: A bundle that registers a Chinese dictionary service
Bundle-Vendor: penngo
Bundle-Version: 1.1.0
Bundle-Activator: tutorial.example2b.Activator
Import-Package: org.osgi.framework, test.penngo.service

插件打包

客户端调用词典开发,也是作为一个felix插件

package tutorial.example3;
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.framework.ServiceReference;
import test.penngo.service.DictionaryService;
 
/**
 * 此客户端在启动时,接收控制台输入,检查输入的单词是否正确,并且打印初相应的检测结果,
  * 注意:当我们没有输入任何信息的时候,单词检测便会结束,如果需要重新进入单词检测程序,我们需要重新启动插件。
**/
public class Activator implements BundleActivator
{
 
    public void start(BundleContext context) throws Exception
    {
        // 获取所有词典插件
        ServiceReference[] refs = context.getServiceReferences(
            DictionaryService.class.getName(), "(Language=*)");
        
        if (refs != null)
        {
        	System.out.println("=======当前可用词典插件:" + refs.length);
            try
            {
                System.out.println("Enter a blank line to exit.");
                BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
                String word = "";
                while (true)
                {
                    System.out.print("Enter word: ");
                    word = in.readLine();
                    if (word.length() == 0)
                    {
                        break;
                    }
 
                    boolean isCorrect = false;
                    for(ServiceReference service:refs) {
                    	DictionaryService dictionary =
                                (DictionaryService) context.getService(service);
                            if (dictionary.checkWord(word))
                            {
                            	isCorrect = true;
                                System.out.println("Correct.");
                            }
                          
                    }
                    if(isCorrect == false)
                    {
                        System.out.println("Incorrect.");
                    }
                }
            } catch (IOException ex) { 
            	ex.printStackTrace();
            }
        }
        else
        {
            System.out.println("Couldn't find any dictionary service...");
        }
    }
 
    /**
     * 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)
    {
        // NOTE: The service is automatically released.
    }
}
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: client
Bundle-Name: Dictionary client
Bundle-Description: A bundle that uses the dictionary service if it finds it at startup
Bundle-Vendor: penngo
Bundle-Version: 1.3.0
Bundle-Activator: tutorial.example3.Activator
Export-Package: test.penngo.service
Import-Package: org.osgi.framework
#//注意:test.penngo.service这个包与tutorial.example3打在同一个jar中,如果example3.jar更新,其它依赖test.penngo.service的也需要更新或重启felix.

安装插件
把上边生成的插件包example2.jar,example2b.jar,example3.jar入到org.apache.felix.main-6.0.3项目的plugins文件夹中
安装和运行效果:

通过插件方式开发,后期继续扩展增加其它语言词典(日语,俄语,韩语),不需要重启服务,也不影响已存在的语言词典功能(英文、中文)。

3、开发http服务插件

package test.penngo.http.example;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class TestServlet extends HttpServlet {
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		resp.getWriter().write("hello penngo");
	}
}
package test.penngo.http.example;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.http.HttpService;
import org.osgi.util.tracker.ServiceTracker;

public class Activator implements BundleActivator {
	private ServiceTracker httpTracker;

	public void start(BundleContext context) throws Exception {
		httpTracker = new ServiceTracker(context, HttpService.class.getName(), null) {
			public void removedService(ServiceReference reference, Object service) {
				// HTTP service is no longer available, unregister our servlet...
				try {
					((HttpService) service).unregister("/hello");
				} catch (IllegalArgumentException exception) {
					// Ignore; servlet registration probably failed earlier on...
				}
			}

			public Object addingService(ServiceReference reference) {
				// HTTP service is available, register our servlet...
				HttpService httpService = (HttpService) this.context.getService(reference);
				try {
					httpService.registerServlet("/hello", new TestServlet(), null, null);
				} catch (Exception exception) {
					exception.printStackTrace();
				}
				return httpService;
			}
		};
		// start tracking all HTTP services...
		httpTracker.open();
	}

	public void stop(BundleContext context) throws Exception {
		// stop tracking all HTTP services...
		httpTracker.close();
	}
}
#MANIFEST.MF
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: hello
Bundle-Name: hello penngo
Bundle-Description: Http Hello World
Bundle-Vendor: penngo
Bundle-Version: 1.0.0
Bundle-Activator: test.penngo.http.example.Activator
Import-Package: org.osgi.framework,
 org.osgi.service.http,
 org.osgi.util.tracker,
 javax.servlet.http,
 javax.servlet

注意htpp插件包依赖:

org.apache.felix.http.base-4.0.6.jar,
org.apache.felix.http.bridge-4.0.8.jar,
org.apache.felix.http.jetty-4.0.10.jar,
org.apache.felix.http.servlet-api-1.1.2.jar,
org.apache.felix.http.whiteboard-4.0.0.jar

需要先安装上边的插件包,才能正常在felix中运行http功能。
安装运行效果

浏览器访问:

附件源码:

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!