扩展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"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www./TR/html4/loose.dtd"> <%@page import="com.dinsotne.web.demo.UserServiceFacade"%> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Insert title here</title> </head> <body> User Name is <%=UserServiceFacade.getUserName("001") %> </body> </html> Step3.修改web.xml文件,添加红色部分。 <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www./2001/XMLSchema-instance" xmlns="http://java./xml/ns/javaee" xmlns:web="http://java./xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java./xml/ns/javaee http://java./xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>webDemo</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <resource-env-ref> <description>osgi service</description> <resource-env-ref-name>osgi/services</resource-env-ref-name> <resource-env-ref-type> com.dinstone.osgi.OsgiServices </resource-env-ref-type> </resource-env-ref> </web-app> 说明: 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.源码工程
|
|
来自: CevenCheng > 《OSGI》