逆仙by衣落成火书包网:扩展Tomcat支持OSGi应用服务(3)

来源:百度文库 编辑:中财网 时间:2024/05/09 02:28:11

扩展Tomcat支持OSGi应用服务(2) Tomcat6.0源码学习-构建Eclipse源码工程扩展Tomcat支持OSGi应用服务(3)  
2009-08-12 14:52:17|  分类: OSGI |字号 订阅 
 4.测试
       通过以上的实现,我们将OSGi平台集成到了Tomcat中,并且明确了web应用如何使用OSGi服务。下面就来创建一个测试的例子,看看OSGi编程模式对web应用开发的影响,同时也测试一下集成的效果。4.1 创建并发布OSGi服务
Step1.创建插件工程com.dinstone.demo.user,选择standard OSGi framework。创建接口:package com.dinstone.demo.user;
 
public interface IUserService {
    public String getUserName(String id);
}

Step2.创建插件工程com.dinstone.demo.user.db,创建类UserServiceImpl实现IUserService接口。package com.dinstone.demo.user.db;
import java.util.logging.Logger;
import com.dinstone.demo.user.IUserService;
 
public class UserServiceImpl implements IUserService {
 
       private static Logger log = Logger.getLogger(UserServiceImpl.class
                     .getName());
 
       @Override
       public String getUserName(String id) {
              log.info("get user name from db");
              return "db" + id;
       }
}

 
Step3.向OSGi平台发布IUserService服务。创建Activator注册服务对象。package com.dinstone.demo.user.db;
 
import java.util.Properties;
 
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
 
import com.dinstone.demo.user.IUserService;
 
public class Activator implements BundleActivator {
 
       private ServiceRegistration serviceReg;
 
       /*
        * (non-Javadoc)
        * 
        * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
        */
       public void start(BundleContext context) throws Exception {
              Properties p = new Properties();
              serviceReg = context.registerService(IUserService.class.getName(),
                            new UserServiceImpl(), p);
       }
 
       /*
        * (non-Javadoc)
        * 
        * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
        */
       public void stop(BundleContext context) throws Exception {
              serviceReg.unregister();
       }
 
}

 
Step4. 创建插件工程com.dinstone.demo.user.file,创建类UserServiceImpl实现IUserService接口。package com.dinstone.demo.user.file;
 
import java.util.logging.Logger;
 
import com.dinstone.demo.user.IUserService;
 
public class UserServiceImpl implements IUserService {
 
       private static Logger log = Logger.getLogger(UserServiceImpl.class
                     .getName());
 
       @Override
       public String getUserName(String id) {
              log.info("get user name from file");
              return "file" + id;
       }
}

 
Step5.向OSGi平台发布IUserService服务。创建Activator注册服务对象。package com.dinstone.demo.user.file;
 
import java.util.Properties;
 
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
 
import com.dinstone.demo.user.IUserService;
 
public class Activator implements BundleActivator {
 
       private ServiceRegistration serviceReg;
 
       /*
        * (non-Javadoc)
        * 
        * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
        */
       public void start(BundleContext context) throws Exception {
              Properties p = new Properties();
              serviceReg = context.registerService(IUserService.class.getName(),
                            new UserServiceImpl(), p);
       }
 
       /*
        * (non-Javadoc)
        * 
        * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
        */
       public void stop(BundleContext context) throws Exception {
              serviceReg.unregister();
       }
}

 4.2 创建Web应用
Step1.创建动态web工程webDemo,并新建类:UserServiceFacade。package com.dinsotne.web.demo;
 
import com.dinsotne.web.osgi.OsgiServiceFacade;
import com.dinstone.demo.user.IUserService;
 
public class UserServiceFacade {
 
       public static String getUserName(String id) {
              try {
                     IUserService service = OsgiServiceFacade.getOsgiService(
                                   "osgi/services", IUserService.class, IUserService.class
                                                 .getName());
 
                     return service.getUserName(id);
              } catch (IllegalArgumentException e) {
                     e.printStackTrace();
                     e.printStackTrace();
              }
 
              return null;
       }
}

 
Step2.创建index.jsp页面。<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="ISO-8859-1"%>

<%@page import="com.dinsotne.web.demo.UserServiceFacade"%>



Insert title here


User Name is
<%=UserServiceFacade.getUserName("001") %>
 



 
Step3.修改web.xml文件,添加红色部分。
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">
    webDemo
   
       index.html
       index.htm
       index.jsp
       default.html
       default.htm
       default.jsp
   

   
       osgi service
       osgi/services
       
           com.dinstone.osgi.OsgiServices
       

   



 
说明:
1. 由于UserServiceFacade依赖IUserService类,故需要将com.dinstone.demo.user_1.0.0.jar(参见4.3)添加到lib中。
2. 由于UserServiceFacade依赖OsgiServiceFacade类,故将com.dinsotne.web.osgi_1.12.0.jar(参见3.4说明)添加到lib中。
 4.3 发布OSGi Bundle
Step1.依次从插件工程导出插件包:com.dinstone.demo.user_1.0.0.jar,com.dinstone.demo.user.file_1.0.0.jar,com.dinstone.demo.user.db_1.0.0.jar。
Step2.将以上的插件放于${Tomcat_Home}\osgi\felix\bundle目录下。
 4.4 发布web应用
Step1.导出web应用webDemo.war。
Step2.将webDemo.war放于${Tomcat_Home}\webapps目录下。
 4.5 启动Tomcat并安装OSGi Bundle
Step1.在命令行下启动Tomcat。E:\Cluster\apache-tomcat-6.0.18为我的${Tomcat_Home}。E:\Cluster\apache-tomcat-6.0.18>bin\startup.bat
Using CATALINA_BASE:   E:\Cluster\apache-tomcat-6.0.18
Using CATALINA_HOME:   E:\Cluster\apache-tomcat-6.0.18
Using CATALINA_TMPDIR: E:\Cluster\apache-tomcat-6.0.18\temp
Using JRE_HOME:        C:\Program Files\Java\jdk1.6.0_10
2009-8-12 13:21:39 com.dinstone.tomcat.osgi.OsgiLifecycleListener lifecycleEvent
信息: The osgi content is initialized. Using osgi content:felix
2009-8-12 13:21:39 org.apache.coyote.http11.Http11Protocol init
信息: Initializing Coyote HTTP/1.1 on http-8080
2009-8-12 13:21:40 org.apache.coyote.http11.Http11Protocol init
信息: Initializing Coyote HTTP/1.1 on http-8443
2009-8-12 13:21:40 org.apache.catalina.startup.Catalina load
信息: Initialization processed in 1748 ms
2009-8-12 13:21:41 com.dinstone.tomcat.osgi.OsgiLifecycleListener lifecycleEvent
信息: Starting osgi service.
2009-8-12 13:21:41 com.dinstone.tomcat.osgi.felix.FelixContent start
信息: *********************************
2009-8-12 13:21:41 com.dinstone.tomcat.osgi.felix.FelixContent start
信息: catalina home is E:\Cluster\apache-tomcat-6.0.18
2009-8-12 13:21:41 com.dinstone.tomcat.osgi.felix.FelixContent start
信息: osgi home is E:\Cluster\apache-tomcat-6.0.18\osgi\felix
2009-8-12 13:21:41 com.dinstone.tomcat.osgi.felix.FelixContent start
信息: ******user.dir is E:\Cluster\apache-tomcat-6.0.18
 
Welcome to Felix.
=================
 
-> 2009-8-12 13:21:42 org.apache.catalina.core.StandardService start
信息: Starting service Catalina
2009-8-12 13:21:42 org.apache.catalina.core.StandardEngine start
信息: Starting Servlet Engine: Apache Tomcat/6.0.18
2009-8-12 13:21:42 org.apache.catalina.loader.WebappLoader start
信息: Dual registration of jndi stream handler: factory already defined
2009-8-12 13:21:44 org.apache.coyote.http11.Http11Protocol start
信息: Starting Coyote HTTP/1.1 on http-8080
2009-8-12 13:21:44 org.apache.coyote.http11.Http11Protocol start
信息: Starting Coyote HTTP/1.1 on http-8443
2009-8-12 13:21:44 org.apache.jk.common.ChannelSocket init
信息: JK: ajp13 listening on /0.0.0.0:8009
2009-8-12 13:21:44 org.apache.jk.server.JkMain start
信息: Jk running ID=0 time=0/47  config=null
2009-8-12 13:21:44 org.apache.catalina.startup.Catalina start
信息: Server startup in 3882 ms
-> ps
START LEVEL 1
   ID   State         Level  Name
[   0] [Active     ] [    0] System Bundle (1.6.0)
[  25] [Active     ] [    1] Apache Felix Shell Service (1.2.0)
[  26] [Active     ] [    1] Apache Felix Shell TUI (1.2.0)
[  27] [Active     ] [    1] Apache Felix Bundle Repository (1.4.0)
->

 
Step2.安装bundle。-> install file:E:\Cluster\apache-tomcat-6.0.18\osgi\felix\bundle\com.dinstone.demo.user_1.0.0.jar
Bundle ID: 39
-> install file:E:\Cluster\apache-tomcat-6.0.18\osgi\felix\bundle\com.dinstone.demo.user.db_1.0.0.jar
Bundle ID: 40
-> install file:E:\Cluster\apache-tomcat-6.0.18\osgi\felix\bundle\com.dinstone.demo.user.file_1.0.0.jar
Bundle ID: 41
-> ps
START LEVEL 1
   ID   State         Level  Name
[   0] [Active     ] [    0] System Bundle (1.6.0)
[  25] [Active     ] [    1] Apache Felix Shell Service (1.2.0)
[  26] [Active     ] [    1] Apache Felix Shell TUI (1.2.0)
[  27] [Active     ] [    1] Apache Felix Bundle Repository (1.4.0)
[  39] [Installed  ] [    1] User Model Interface Plug-in (1.0.0)
[  40] [Installed  ] [    1] User DB Implement Plug-in (1.0.0)
[  41] [Installed  ] [    1] User File Implement Plug-in (1.0.0)
->

Step3.访问web应用,http://localhost:8080/webDemo/。由于没有启动OSGi服务,故出现500异常页面,错误原因是没有找到服务。root cause com.dinsotne.web.osgi.IllegalServiceException: Cann't find out osgi service:com.dinstone.demo.user.IUserService        com.dinsotne.web.osgi.OsgiServiceInvocationHandler.invoke(OsgiServiceInvocationHandler.java:30)        $Proxy0.getUserName(Unknown Source)        com.dinsotne.web.demo.UserServiceFacade.getUserName(UserServiceFacade.java:14)        org.apache.jsp.index_jsp._jspService(index_jsp.java:64)        org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)        javax.servlet.http.HttpServlet.service(HttpServlet.java:717)        org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)        org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)        org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)        javax.servlet.http.HttpServlet.service(HttpServlet.java:717) 

 
Step4.启动User DB Implement Plug-in服务,激活User模块的DB实现。->ps
START LEVEL 1
   ID   State         Level  Name
[   0] [Active     ] [    0] System Bundle (1.6.0)
[  25] [Active     ] [    1] Apache Felix Shell Service (1.2.0)
[  26] [Active     ] [    1] Apache Felix Shell TUI (1.2.0)
[  27] [Active     ] [    1] Apache Felix Bundle Repository (1.4.0)
[  39] [Installed  ] [    1] User Model Interface Plug-in (1.0.0)
[  40] [Installed  ] [    1] User DB Implement Plug-in (1.0.0)
[  41] [Installed  ] [    1] User File Implement Plug-in (1.0.0)
-> start 40
-> ps -s
START LEVEL 1
   ID   State         Level  Symbolic name
[   0] [Active     ] [    0] org.apache.felix.framework (1.6.0)
[  25] [Active     ] [    1] org.apache.felix.shell (1.2.0)
[  26] [Active     ] [    1] org.apache.felix.shell.tui (1.2.0)
[  27] [Active     ] [    1] org.apache.felix.bundlerepository (1.4.0)
[  39] [Resolved   ] [    1] com.dinstone.demo.user (1.0.0)
[  40] [Active     ] [    1] com.dinstone.demo.user.db (1.0.0)
[  41] [Installed  ] [    1] com.dinstone.demo.user.file (1.0.0)
->

访问http://localhost:8080/webDemo/。页面显示:



 
Step5. 启动User File Implement Plug-in服务,激活User模块的File实现。-> ps
START LEVEL 1
   ID   State         Level  Name
[   0] [Active     ] [    0] System Bundle (1.6.0)
[  25] [Active     ] [    1] Apache Felix Shell Service (1.2.0)
[  26] [Active     ] [    1] Apache Felix Shell TUI (1.2.0)
[  27] [Active     ] [    1] Apache Felix Bundle Repository (1.4.0)
[  39] [Resolved   ] [    1] User Model Interface Plug-in (1.0.0)
[  40] [Active     ] [    1] User DB Implement Plug-in (1.0.0)
[  41] [Installed  ] [    1] User File Implement Plug-in (1.0.0)
-> start 41
-> ps
START LEVEL 1
   ID   State         Level  Name
[   0] [Active     ] [    0] System Bundle (1.6.0)
[  25] [Active     ] [    1] Apache Felix Shell Service (1.2.0)
[  26] [Active     ] [    1] Apache Felix Shell TUI (1.2.0)
[  27] [Active     ] [    1] Apache Felix Bundle Repository (1.4.0)
[  39] [Resolved   ] [    1] User Model Interface Plug-in (1.0.0)
[  40] [Active     ] [    1] User DB Implement Plug-in (1.0.0)
[  41] [Active     ] [    1] User File Implement Plug-in (1.0.0)
->

 
访问http://localhost:8080/webDemo/。页面显示:

 
 
Step6.现在停止User DB Implement Plug-in服务。-> ps
START LEVEL 1
   ID   State         Level  Name
[   0] [Active     ] [    0] System Bundle (1.6.0)
[  25] [Active     ] [    1] Apache Felix Shell Service (1.2.0)
[  26] [Active     ] [    1] Apache Felix Shell TUI (1.2.0)
[  27] [Active     ] [    1] Apache Felix Bundle Repository (1.4.0)
[  39] [Resolved   ] [    1] User Model Interface Plug-in (1.0.0)
[  40] [Active     ] [    1] User DB Implement Plug-in (1.0.0)
[  41] [Active     ] [    1] User File Implement Plug-in (1.0.0)
-> stop 40
-> ps
START LEVEL 1
   ID   State         Level  Name
[   0] [Active     ] [    0] System Bundle (1.6.0)
[  25] [Active     ] [    1] Apache Felix Shell Service (1.2.0)
[  26] [Active     ] [    1] Apache Felix Shell TUI (1.2.0)
[  27] [Active     ] [    1] Apache Felix Bundle Repository (1.4.0)
[  39] [Resolved   ] [    1] User Model Interface Plug-in (1.0.0)
[  40] [Resolved   ] [    1] User DB Implement Plug-in (1.0.0)
[  41] [Active     ] [    1] User File Implement Plug-in (1.0.0)
->

 
访问http://localhost:8080/webDemo/。页面显示:

 
 4.6 停止Tomcat服务器
重新打开一个命令行窗口,切换到${Tomcat_Home}\bin目录下。执行:E:\Cluster\apache-tomcat-6.0.18\bin>shutdown.bat

Tomcat服务器关闭。5结论
       通过以上的测试,我们发现以上的实现基本符合最初的设想:
l         OSGi的集成对Tomcat几乎是透明的。
l         OSGi的所有优点。
l         Web表现和业务逻辑的完全分离。
l         基于模块化服务的编程模型。
 
同时,我们也发现了一些问题:
l         Web层没有支持模块化、可热插拔的编程模型。
l         OSGi层的服务日志跟web层的日志分离增加了维护的难度。
l         该集成方式没有经严格测试,虽然已经有产品应用了。附录:1.测试Demo
…2.源码工程