程序人生

在Java中摸爬滚打的日子

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  6 Posts :: 1 Stories :: 19 Comments :: 0 Trackbacks

基于OSGiWeb应用开发系列三


搭建项目框架

    

1. 目标

这一章的目标是:通过新建一个基于MavenOSGiWeb应用框架,来介绍OSGiWeb应用框架的搭建过程。基于这项目框架,你可以添加自己的业务模块进来,很容易就能使之应用于实际项目中。

在这个例子中,我将以用户登录模块,结合SSH框架来演示整个过程,后端数据库将采用内存数据库。当然这个例子将贯穿接下来的几个篇章。


2. 新建项目



a. 项目结构

项目结构如下:

osgiapp

|---poms

    |    |---compiled

|    |---wrappers

    |---provision

|---osgiapp-webapp

|---osgiapp-login

|      |---osgiapp-login-dto

|      |---osgiapp-login-domain

|      |---osgiapp-login-repository-impl

|      |---osgiapp-login-service

|      |---osgiapp-login-service-impl

|---othermodule

在这个项目的层次结构中,以上列出来的均是目录结构,第一层表示项目的顶级目录,poms目录下有两个子目录跟一个pom.xml文件,此pom.xml文件继承自顶级目录下的pom.xml文件,而此pom.xml文件又被compiledwrappers子目录下的pom.xml文件所继承。compiled下的pom.xml是项目编译所依赖的pom文件,所有业务模块下的pom.xml均继承自此pom文件,而wrappers目录下的pom.xml文件是用来被改造成OSGi下的Bundle的工程继承之用。比如我们可能需要用到第三方的某个工具包,但此工具包却不是OSGi下的Bundle,且在SpringSourceEBR中也找不到,那我们就需要自己动手来将其改造成OSGi下的Bundle,这个待会在相关的章节中以示例操作给大家看。

根目录下的provision文件夹中也有一个pom.xml文件,这个xml文件主要是用来提供给Pax-Runner运行项目所用。因此项目运行所需要的依赖包,最好全部罗列于此。

webapp目录是这个项目的web应用的一个子模块(Maven的子工程),当然你也可以添加多个web应用,这个还是看需求而定吧。而osgiapp-login是这个应用的所要展示用的登录模块,这个登录模块又被划分成五个了工程,也就是五个Bundle,在OSGi中都是面向接口编程,所有服务都是基于接口(当然OSGi也是允许服务基于类,但我不推荐大家这样做),这样划分的目的是为了做到松耦合,高内聚吧。

在登录模块中的这五个子工程中,osgiapp-login-dto层表示的是数据传输对象、osgiapp-login-domain层表示的是领域对象、osgiapp-login-repository-impl表示的是数据仓储的实现,而这个数据仓储的接口均位于领域对象层,osgiapp-login-service表示业务服务层,osgiapp-login-service-impl表示的是业务服务层的实现。相关领域驱动设计的概念之类的东西,推荐大家参考彬哥的博客领域驱动设计系列文章http://www.blogjava.net/johnnylzb/archive/2010/05/15/321057.html。

最后othermodel表示的就是其他模块了,其分层原则最好是根登录模块一样。


b. Pax-Construct构建项目

Pax-Constructbin目录下有几个我们比较常用的脚本文件,pax-create-project.batpax-create-module.batpax-create-bundle.batpax-wrap-jar.bat。其中pax-create-project.bat是用来创建工程的,它会生成如下所示的工程结构:

xxxProject

|---poms

    |     |---compiled

|     |---wrappers

    |---provision

pax-create-module.bat是用来创建模块的,如上面的loginmoduleothermodule等。pax-create-bundle.bat则是用来创建具体的Bundle的。比如上面的dtodomain等。pax-wrap-jar.bat则是用来包装非OSGi的jarBundle

具体使用方式如下:

pax-create-project指令使用如下:

pax-create-project -g org.ideawork.osgiapp -a osgiapp -v 1.0.0

-g 是在maven项目中所指的groupId
   
-a 是在maven项目中所指的artifactId
   
-v 是在maven项目中所指的version
   
具体细节可以参考官方
   
http://www.ops4j.org/projects/pax/construct/help/create-project.html

pax-create-module指令使用如下:

cd osgiapp

pax-create-module -g org.ideawork.osgiapp -a osgiapp-login -v 1.0.0

参数意义同上。

具体细节可以参考官方网站:

http://www.ops4j.org/projects/pax/construct/help/create-module.html

pax-create-bundle.指令使用如下:

cd osgiapp

pax-create-bundle -p org.ideawork.osgiapp.login.domain -n osgiapp-login-domain -g org.ideawork.osgiapp.login -v 1.0.0 -- -Djunit "-Dactivator=false"

-pPackage,指包名
   
-nBundleName,指Bundle的名称,同artifactId
   
-Djunit使用该参数主要是为了自动产生src/test目录
   
-Dactivator=false不需为bundle提供一个Activator
  
具体细节可以参考官方网站:
  
http://www.ops4j.org/projects/pax/construct/help/create-bundle.html

pax-wrap-jar指令使用如下:

这里是将groupIdmysql,artifactIdmysql-connector-java,version5.1.7的普通jar包包装成OSGi下的Bundle。

依次执行上面的三个指令,就可以创建上面所绘的项目结构,但凡在项目初期,一般都会新建很多的业务模块,如果用以上方式通过命令一个一个的新建但凡不可,只是觉得有点烦燥乏味。如果我们通过自己编写一批处理文件,在批处理文件里写好各模块的相关参数,再通过执行批处理来帮我们创建想要的新项目岂不更好。如是新建createProjects.bat如下:

pax-wrap-jar -g mysql -a mysql-connector-java -v 5.1.7

cd %~dp0

call pax-create-project -g org.ideawork.osgiapp -a osgiapp -v 1.0.0

cd osgiapp

call pax-create-module -g org.ideawork.osgiapp -a osgiapp-login -v 1.0.0

cd osgiapp-login

call pax-create-bundle -p org.ideawork.osgiapp.login.dto -n osgiapp-login-dto -g org.ideawork.osgiapp.login -v 1.0.0 

call pax-create-bundle -p org.ideawork.osgiapp.login.domain -n osgiapp-login-domain -g org.ideawork.osgiapp.login -v 1.0.0 -- -Djunit "-Dactivator=false"

call pax-create-bundle -p org.ideawork.osgiapp.login.repository.impl -n osgiapp-login-repository-impl -g org.ideawork.osgiapp.login -v 1.0.0 -- -Djunit "-Dactivator=false"

call pax-create-bundle -p org.ideawork.osgiapp.login.service -n osgiapp-login-service -g org.ideawork.osgiapp.login -v 1.0.0 

call pax-create-bundle -p org.ideawork.osgiapp.login.service.impl -n osgiapp-login-service-impl -g org.ideawork.osgiapp.login -v 1.0.0 -- -Djunit "-Dactivator=false"

cd ..

call pax-create-bundle -p org.ideawork.osgiapp.webapp -n osgiapp-webapp -g org.ideawork.osgiapp -v 1.0.0 -- -Djunit "-Dactivator=false"

cmd

将以上批处理文件保存到想要创建项目的根目录下,双击运行即可,当然前提条件是你要按照系列二工具介绍中所说的安装好Maven、Pax-Construct等工具。


c. 导入IDE环境

空项目创建完成后,我们将其导入到我们的IDE中来,这里指的是Eclipse,希望你们的Eclipse里已经安装了Maven的插件,这样的话,将项目导入到Eclipse里将很容易,仅需一步就可以搞定。

具体操作:File--->Import--->General--->Maven Projects,选择主工程就可以了。

如下图:


poms、poms" compiled、poms" wrappers、provision这几个子模块不需要做为eclipse工程导入到eclipse,因为这几个项目的内容都是一些pom文件,我们不需要以工程的方式维护这些子模块。osgiapp-login是登录模块的主工程,可以选择导入也可以不导入。

导入的工程如下所示:


3. 修改配置

经过以上几步,项目已经初具锥形。现在我们就来简单的修改一下相关的配置文件,将项目调整成我们想要的结构。


1) 将根项目下的pom.xml文件中的“felix”改成“equinox”,如下:

这里是设置OSGi所使用的平台的类型,我们将采用OSGi的参考实现equinox,也是Eclipse核心。

你还可以在这里添加远程调度的参数,如下:

<provision>

     <param>--platform=felix</param>

</provision>

需要注意的是,“--vmOptions=”这后面的一大串是不能换行的。

2) osgiapp-login-repository-implosgiapp-login-service-impl两模块下的pom.xml文件中的properties属性下的bundle.symbolicName中的“-”改成“.”,虽然不改也没问题,只是org.ideawork.osgiapp.login.repository-implsymbolicName看起来怪怪的。另外将这两个Bundle工程下的pom.xml文件中的name元素内容中的“[${bundle.namespace}]”删掉,因为我们的BundlesymbolicNamenamespace内容是一样的,没必要重复表示。但这两点也都是无关紧要的。

3) 最后需要调整的配置是webapp,因为现在的webapp默认是一个bundle工程,并非符合J2EE规范的Web工程。将默认的bundle工程改成web工程需要如下几步:

a) 首先修改poms/compiled/pom.xml文件,在里面添加一个Maven的插件来支持web工程的一些相关处理,如下:

<provision>

     <param>--platform=equinox</param>

<param>--vmOptions=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000</param>

</provision>

<plugin>

<artifactId>maven-war-plugin</artifactId>

<configuration>

<archive><manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile><addMavenDescriptor>false</addMavenDescriptor> 

</archive><warSourceDirectory>src/webapp</warSourceDirectory> <warSourceExcludes>WEB-INF/lib/*</warSourceExcludes>

</configuration>

</plugin>

作为OSGi下的一个web Bundle,我们需要将其WEB-INF/lib/目录下的所有jar文件排除掉,并且还需要提供一份MANIFEST.MF文件来给Maven打包。而这MANIFEST.MF文件需要借助Mavenbnd工具为其生成,这个在通过Pax-Construct新建项目的时候就由Pax-Construct集成进项目框架之中,我们只需运行mvn packageinstall等命令就可以自动生成。

b) 根据以上maven-war-plugin的配置信息,我们还需要在webapp Bundlesrc目录下添加webapp资源文件夹,并且需要在此文件夹中添加WEB-INF/web.xml文件,这样才符合MavenWeb工程结构。

c) 接着修改上面所说的那个pom.xml文件(poms/compiled/pom.xml)中的maven-bundle-plugin插件,在这插件的configuration元素内添加如下内容:

最后在configuration元素后面添加如下内容:

<supportedProjectTypes>

<supportedProjectType>war</supportedProjectType>

<supportedProjectType>jar</supportedProjectType>

<supportedProjectType>bundle</supportedProjectType>

</supportedProjectTypes>

<executions>

<execution>

<id>bundle-manifest</id>

<phase>process-classes</phase>

<goals>

<goal>manifest</goal>

</goals>

</execution>

</executions>

如此poms/compiled/pom.xml文件修改完毕。

d) 到此为止,pom文件的修改还有最后一处,那就是osgiap-webapp这个Bundlepom.xml文件的packaging元素的类型,我们需要将bundle改成war

4) 到这里,Maven的配置文件的修改已经完成。此时,我们可以在命令行下运行此OSGi的项目,具体步骤如下:

a) 在命令行下进入到项目根目录下

b) 运行mvn pax:provision命令即可

注意事项:运行此命令会在根目录下生成一个runner的文件夹,此文件夹下有bundlesequinox两个子目录,其结构如下:

  runner

|---bundles

|     |---*.jar

|---equinox

|     |----config.ini

|---deploy-pom.xml

其中bundles下面是项目所有的Bundle,包括项目自身的Bundle跟第三方的Bundle,而equinox目录下只有一份config.ini文件,这是equinox启动时需要加载的配置文件,里面有很多的配置信息,比如系统路径、启动级别、需要加载的Bundles等。

第一次运行mvn pax:provision命令,需要有网络支持,因为此时pax-runner插件会去远程服务器上下载相关的依赖包。如果没有网络,会导致启动失败,如下所示:


会出现一个很大的感叹号。如果成功的话,会出现如下所示画面:


此时我们可以在控制台中输入“ss”命令来查看所有Bundle的状态信息,如下:

   

关于更多OSGi控制台命令,请参考OSGi equinox实现的相关资料,你也可以直接在命令行下输入help来得到相关帮助信息。



4. 整合SSH框架

经过了以上的操作,这个OSGi环境下的工程基本可以运行起来了,但是现在其仅仅只是一个OSGi的工程而已,因为并没有整合SSH框架进来。所以这一节的目的就是整合SSH框架进来。

整合SSH框架进来,最原始的做法就是逐个添加依赖的Bundle以达到目的,另一个办法就是去Spring-DM的官方网站,参考其相关的示例程序,拷贝相应的Maven依赖,然后再测试以达到目的。而我之前的做法就是根据已经确定好的几个核心包(这里所说的核心包就是Spring-DM的五个包加上Hibernate的三个包,再加上Struts的一个包),将其添加到Mavenpom.xml文件中,再运行mvn dependency:tree命令打印整棵依赖树出来,再添加相应的依赖到pom.xml文件中,然后启动测试,查找所缺少的Bundle,将其添加进来。当然,这样的尝试确实挺耗时间,但当你整理了一份完整的SSH框架的Bundle清单出来后,以后再搭建这框架时,就不需要如此麻烦了。

还有一点就是光有了SSH框架的依赖包,在启动项目的时候,还是会出现“java.lang.NoClassDefFoundError: org/apache/catalina/Loader”之类的异常,这是因为Spring-DM默认使用的Web服务组件是tomcat,这里之所以说Web服务组件而不说Web容器,这是因为在OSGi环境下面,不存在以往的Web容器,而都是以服务的方式来供OSGi环境下的其他组件来使用。所以在OSGi环境下的Tomcat也成了内嵌于OSGi容器的服务组件。

另外需要说明的一点是,我们所有的第三方Bundle均来自于springsourceEBR仓库,因此我们需要在osgiapp根目录下的pom.xml文件中添加如下Maven仓库地址:

  <repositories>

    <repository>

      <id>maven2</id>

      <url>http://repo1.maven.org/maven2/</url>

    </repository>

    <repository>

      <id>com.springsource.repository.bundles.release</id>

      <name>SpringSource Enterprise Bundle Repository - SpringSource Bundle Releases</name>

      <url>http://repository.springsource.com/maven/bundles/release</url>

    </repository>

    <repository>

      <id>com.springsource.repository.bundles.external</id>

      <name>SpringSource Enterprise Bundle Repository - External Bundle Releases</name>

      <url>http://repository.springsource.com/maven/bundles/external</url>

    </repository>

    <repository>

      <id>spring-release</id>

      <name>Spring Portfolio Release Repository</name>

      <url>http://maven.springframework.org/release</url>

    </repository>

    <repository>

      <id>i21-s3-osgi-repo</id>

      <name>i21 osgi artifacts repo</name>

      <snapshots>

        <enabled>true</enabled>

        <updatePolicy>never</updatePolicy>

        <checksumPolicy>warn</checksumPolicy>

      </snapshots>

      <url>http://maven.springframework.org/osgi</url>

    </repository>

  </repositories>

至于整理SSH框架所有依赖的详细过程,我就不具体描述了,下面我将列出一份可用的SSH框架的Maven依赖清单。但在这份清单文件中,还有两三个Bundle是需要我们来修改或提供的,这在系列一中也有说到。

<dependency>

     <groupId>javax.servlet</groupId>

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

<version>2.5.0</version>

</dependency>

<dependency>

<groupId>javax.persistence</groupId>

<artifactId>com.springsource.javax.persistence</artifactId>

<version>1.0.0</version>

</dependency>

<dependency>

<groupId>javax.annotation</groupId>

<artifactId>com.springsource.javax.annotation</artifactId>

<version>1.0.0</version>

</dependency>

<dependency>

<groupId>javax.el</groupId>

<artifactId>com.springsource.javax.el</artifactId>

<version>1.0.0</version>

</dependency>

<dependency>

<groupId>javax.activation</groupId>

<artifactId>com.springsource.javax.activation</artifactId>

<version>1.1.1</version>

</dependency>

<dependency>

<groupId>javax.mail</groupId>

  <artifactId>com.springsource.javax.mail</artifactId>

  <version>1.4.1</version>

</dependency>

<dependency>

<groupId>javax.transaction</groupId>

<artifactId>com.springsource.javax.transaction</artifactId>

<version>1.1.0</version>

</dependency>

<dependency>

<groupId>org.apache.commons</groupId>

<artifactId>com.springsource.org.apache.commons.lang</artifactId>

<version>2.4.0</version>

</dependency>

<dependency>

<groupId>org.apache.commons</groupId>

<artifactId>com.springsource.org.apache.commons.logging</artifactId>

<version>1.1.1</version>

</dependency>

<dependency>

<groupId>org.apache.commons</groupId>

<artifactId>com.springsource.org.apache.commons.collections</artifactId>

<version>3.2.1</version>

</dependency>

<dependency>

<groupId>org.apache.commons</groupId>

<artifactId>com.springsource.org.apache.commons.beanutils</artifactId>

<version>1.8.0</version>

</dependency>

<dependency>

<groupId>org.apache.commons</groupId>

<artifactId>com.springsource.org.apache.commons.digester</artifactId>

<version>1.8.1</version>

</dependency>

<dependency>

<groupId>org.antlr</groupId>

<artifactId>com.springsource.antlr</artifactId>

<version>2.7.6</version>

</dependency>

<!-- SpringDM Bundle -->

<dependency>

<groupId>org.springframework.osgi</groupId>

<artifactId>org.springframework.osgi.core</artifactId>

<version>${springDm.version}</version>

</dependency>

<dependency>

<groupId>org.springframework.osgi</groupId>

<artifactId>org.springframework.osgi.extender</artifactId>

<version>${springDm.version}</version>

</dependency>

<dependency>

<groupId>org.springframework.osgi</groupId>

<artifactId>org.springframework.osgi.io</artifactId>

<version>${springDm.version}</version>

</dependency>

<dependency>

<groupId>org.springframework.osgi</groupId>

<artifactId>org.springframework.osgi.web</artifactId>

<version>${springDm.version}</version>

</dependency>

<dependency>

<groupId>org.springframework.osgi</groupId>

<artifactId>

org.springframework.osgi.web.extender

</artifactId>

<version>${springDm.version}</version>

</dependency>

<!-- SpringDM Depend springframework bundles -->

<dependency>

<groupId>org.springframework</groupId>

<artifactId>org.springframework.aop</artifactId>

<version>${spring.version}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>org.springframework.beans</artifactId>

<version>${spring.version}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>org.springframework.context</artifactId>

<version>${spring.version}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>org.springframework.core</artifactId>

<version>${spring.version}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>org.springframework.web</artifactId>

<version>${spring.version}</version>

</dependency>

<!--其他 Springframework  Bundles -->

<dependency>

<groupId>org.springframework</groupId>

<artifactId>org.springframework.orm</artifactId>

<version>${spring.version}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>org.springframework.context.support</artifactId>

<version>${spring.version}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>org.springframework.jdbc</artifactId>

<version>${spring.version}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>org.springframework.transaction</artifactId>

<version>${spring.version}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>org.springframework.aspects</artifactId>

<version>${spring.version}</version>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>org.springframework.web.servlet</artifactId>

<version>${spring.version}</version>

</dependency>

<!-- 如果用到Struts就需要这个Bundle -->

<dependency>

<groupId>org.springframework</groupId>

<artifactId>org.springframework.web.struts</artifactId>

<version>${spring.version}</version>

</dependency>

<!-- Springframework 依赖的 Bundles -->

<dependency> 

<groupId>org.aopalliance</groupId>

<artifactId>com.springsource.org.aopalliance</artifactId>

<version>1.0.0</version>

</dependency>

<dependency>

<groupId>org.aspectj</groupId>

<artifactId>com.springsource.org.aspectj.runtime</artifactId>

<version>1.6.1</version>

</dependency>

<dependency>

<groupId>org.aspectj</groupId>

<artifactId>com.springsource.org.aspectj.weaver</artifactId>

<version>1.6.1</version>

</dependency>

<!-- TOMCAT -->

<dependency><!-- 需要一个包含有相关配置文件的Fragment-->

<groupId>org.apache.catalina</groupId>

<artifactId>com.springsource.org.apache.catalina</artifactId>

<version>${catalina.version}</version>

</dependency>

<dependency>

<groupId>org.apache.catalina</groupId>

<artifactId>com.springsource.org.apache.catalina.ha</artifactId>

<version>${catalina.version}</version>

</dependency>

<dependency>

<groupId>org.apache.catalina</groupId>

<artifactId>com.springsource.org.apache.catalina.tribes</artifactId>

<version>${catalina.version}</version>

</dependency>

<dependency>

<groupId>org.apache.coyote</groupId>

<artifactId>com.springsource.org.apache.coyote</artifactId>

<version>${catalina.version}</version>

</dependency>

<dependency><!-- dependency by: org.apache.catalina -->

<groupId>org.apache.juli</groupId>

<artifactId>com.springsource.org.apache.juli.extras</artifactId>

<version>${catalina.version}</version>

</dependency>

<dependency>

<groupId>org.apache.jasper</groupId>

<artifactId>com.springsource.org.apache.jasper</artifactId>

<version>${catalina.version}</version>

</dependency>

<dependency>

<groupId>org.apache.el</groupId>

<artifactId>com.springsource.org.apache.el</artifactId>

<version>${catalina.version}</version>

</dependency>

<dependency>

<groupId>org.apache.jasper</groupId>

<artifactId>

com.springsource.org.apache.jasper.org.eclipse.jdt

</artifactId>

<version>${catalina.version}</version>

</dependency>

<dependency><!-- 需要一个包含有相关配置文件的Fragment -->

<groupId>org.springframework.osgi</groupId>

<artifactId>catalina.start.osgi</artifactId>

<version>1.0.0</version>

</dependency>

<dependency>

<groupId>javax.ejb</groupId>

<artifactId>com.springsource.javax.ejb</artifactId>

<version>3.0.0</version>

</dependency>

<dependency>

<groupId>javax.xml.rpc</groupId>

<artifactId>com.springsource.javax.xml.rpc</artifactId>

<version>1.1.0</version>

</dependency>

<dependency>

<groupId>javax.xml.soap</groupId>

<artifactId>com.springsource.javax.xml.soap</artifactId>

<version>1.3.0</version>

</dependency>

<dependency><!-- dependency by: org.apache.catalina -->

<groupId>javax.xml.ws</groupId>

<artifactId>com.springsource.javax.xml.ws</artifactId>

<version>2.1.1</version>

</dependency>

<dependency><!-- dependency by: javax.xml.ws -->

<groupId>javax.xml.bind</groupId>

<artifactId>com.springsource.javax.xml.bind</artifactId>

<version>2.1.7</version>

</dependency>

<dependency><!-- dependency by: javax.xml.bind -->

<groupId>javax.xml.stream</groupId>

<artifactId>com.springsource.javax.xml.stream</artifactId>

<version>1.0.1</version>

</dependency>

<!-- JSP及相关的Bundle -->

<dependency>

<groupId>javax.servlet</groupId>

<artifactId>com.springsource.javax.servlet.jsp</artifactId>

<version>2.1.0</version>

</dependency>

<dependency>

<groupId>javax.servlet</groupId>

<artifactId>com.springsource.javax.servlet.jsp.jstl</artifactId>

<version>1.1.2</version>

</dependency>

<dependency>

<groupId>org.apache.taglibs</groupId>

<artifactId>com.springsource.org.apache.taglibs.standard</artifactId>

<version>1.1.2</version>

</dependency>

<!-- STRUTS -->

<dependency>

<groupId>org.apache.struts</groupId>

<artifactId>com.springsource.org.apache.struts</artifactId>

<version>${struts.version}</version>

</dependency>

<dependency>

<groupId>org.apache.commons</groupId>

<artifactId>com.springsource.org.apache.commons.fileupload</artifactId>

<version>1.2.0</version>

</dependency>

<dependency>

<groupId>org.apache.commons</groupId>

<artifactId>com.springsource.org.apache.commons.validator</artifactId>

<version>1.1.4</version>

</dependency>

<!-- com.springsource.org.apache.commons.fileupload 依赖的Bundle -->

<dependency>

<groupId>org.apache.commons</groupId>

<artifactId>com.springsource.org.apache.commons.io</artifactId>

<version>1.4.0</version>

</dependency>

<!-- com.springsource.org.apache.commons.validator 依赖的Bundle -->

<dependency>

<groupId>org.apache.oro</groupId>

<artifactId>com.springsource.org.apache.oro</artifactId>

<version>2.0.8</version>

</dependency>

<!-- HIBERNATE -->

<dependency>

<groupId>org.hibernate</groupId>

<artifactId>com.springsource.org.hibernate</artifactId>

<version>3.2.6.ga</version>

<exclusions>

<exclusion>

<groupId>net.sourceforge.cglib</groupId>

<artifactId>com.springsource.net.sf.cglib</artifactId>

</exclusion>

</exclusions>

</dependency>

<dependency>

<groupId>org.hibernate</groupId>

<artifactId>com.springsource.org.hibernate.annotations</artifactId>

<version>3.3.1.ga</version>

</dependency>

<dependency>

<groupId>org.hibernate</groupId>

<artifactId>com.springsource.org.hibernate.annotations.common</artifactId>

<version>3.3.0.ga</version>

</dependency>

<!-- 由com.springsource.org.hibernate依赖进来的Bundle -->

<dependency>

<groupId>org.jboss.javassist</groupId>

<artifactId>com.springsource.javassist</artifactId>

<version>3.3.0.ga</version>

</dependency>

<dependency>

<groupId>org.dom4j</groupId>

<artifactId>com.springsource.org.dom4j</artifactId>

<version>1.6.1</version>

</dependency>

<dependency>

<groupId>org.objectweb.asm</groupId>

<artifactId>com.springsource.org.objectweb.asm</artifactId>

<version>1.5.3</version>

</dependency>

<dependency>

<groupId>org.objectweb.asm</groupId>

<artifactId>

com.springsource.org.objectweb.asm.attrs

</artifactId>

<version>1.5.3</version>

</dependency>

<dependency>

<groupId>com.mchange.c3p0</groupId>

<artifactId>com.springsource.com.mchange.v2.c3p0</artifactId>

<version>0.9.1.2</version>

</dependency>

<!-- 改造过的cglib mysql-connector-jar -->

<dependency>

<groupId>org.ideawork.osgiapp.warpper</groupId>

<artifactId>org.ideawork.net.sf.cglib</artifactId>

<version>2.1.3</version>

</dependency>

<dependency>

<groupId>org.ideawork.osgiapp.warpper</groupId>

<artifactId>org.ideawork.mysql.connector.java</artifactId>

<version>5.1.7</version>

</dependency>

<!-- com.springsource.org.apache.catalinaFragment -->

<dependency>

<groupId>org.ideawork.osgiapp.fragment</groupId>

<artifactId>org.ideawork.osgiapp.fragment.tomcat.conf</artifactId>

<version>1.0.0</version>

</dependency>

<!-- catalina.start.osgi Fragment -->

<dependency>

<groupId>org.ideawork.osgiapp.fragment</groupId>

<artifactId>org.ideawork.osgiapp.fragment.tomcat.start.conf</artifactId>

<version>1.0.0</version>

</dependency>

上面列出的Maven依赖中,cglibmysql-connector-jar是自己改造过的,还有Tomcat相关的两个Bundle com.springsource.org.apache.catalinacatalina.start.osgi需要提供相关配置文件的Fragment。如果没有这两个Fragmentweb应用就无法正常访问。这几个改造的BundleFragment我会在后续的篇章里来详细介绍。

上面的Maven依赖中用到的几个属性如下:

<properties>
    <springDm.version>1.2.1</springDm.version>
    <
spring.version>2.5.6.SEC01</spring.version>
    <
catalina.version>6.0.18</catalina.version>
    <
struts.version>1.2.9</struts.version>
</properties>

这里所说的整合SSH框架,其实不尽然。因为到现在为止,只是整合了SSH框架所有的依赖包,而相关的SSH的配置文件,尚未提到,但请不要急,这些将在接下来的篇章中来详细介绍。



5. 完善webapp

当前的webapp还不符合Spring-DMWeb应用的要求,要使Spring-DM能识别其为Web应用,则需要在其MANIFEST.MF文件中添加如下信息:

Export-Package = ""

Import-Package = javax.servlet;version="2.4.0", "

 javax.servlet.http;version="2.4.0", "

 javax.servlet.jsp;version="2.0.0", "

 javax.servlet.jsp.jstl.core;version="1.1.2", "

 javax.servlet.jsp.jstl.fmt;version="1.1.2", "

 javax.servlet.jsp.jstl.tlv;version="1.1.2", "

 javax.servlet.resources;version="2.0.0", "

 org.apache.struts.config;version="1.2.9", "

 org.apache.struts.config.impl;version="1.2.9", "

 org.apache.struts.util;version="1.2.9", "

 org.apache.taglibs.standard.resources;version="1.1.2", "

 org.apache.taglibs.standard.tag.common.core;version="1.1.2", "

 org.apache.taglibs.standard.tag.rt.core;version="1.1.2", "

 org.apache.taglibs.standard.tei;version="1.1.2", "

 org.apache.taglibs.standard.tlv;version="1.1.2", "

 org.springframework.web.context;version="2.5.6", "

 org.springframework.web.filter;version="2.5.6", "

 org.springframework.web.struts;version="2.5.6", "

 *

Require-Bundle = org.springframework.osgi.core, "

 org.springframework.osgi.extender, "

 org.springframework.osgi.io, "

 org.springframework.osgi.web, "

 org.springframework.osgi.web.extender

Bundle-ClassPath = .,WEB-INF/classes

Web-ContextPath = osgiapp

DynamicImport-Package = *

其中Web-ContextPath = osgiapposgiappWeb应用的应用名,这跟具体的应用相关。当然在MANIFEST.MF文件远中不止这些内容,而上面的内容我们也只是添加在webapp子工程根目录下的osgi.bnd文件中,其他的元素数信息我们可以通过Maven Bnd 工具为我们生成。

Export-Package = ""表示不需要导出任何包,因为这是webapp Bundle,其只会消费OSGi服务跟使用其他Bundle导出的包。当然,如果你有此需求,也是可以导出相应的包的。

Import-Package中为什么还需要写这么多的包呢,为什么不借助Maven Bnd工具为我们生成呢?其实原因很简单,那就是Bnd不是万能的,它只能解析Java类文件中的import来生成BundleMANIFEST.MF文件中的元数据,至于JSP页面会用到哪些包,Spring Bean的配置文件中有用到哪些包等,其都不会去解析。因此我们就需要手动的在osgi.bnd文件中添加这么多的Import-Package信息。

DynamicImport-Package = *是什么意思呢,这是OSGi的一个动态导包元信息,其中星号可以用任何包代替。如果你需要对某个包进行动态导入(意思就是在使用的时候才去从OSGi容器中查找相应的包来导入),你就可以这样配。但这个会影响到性能,因此不太推荐使用。

Require-Bundle也尽量少用,如果自己清楚自己的项目用到哪几些包,那就直接Import-Package那些包好了。



6. 测试Web应用

完成上面所有的修修改改后,我们在src/webapp下面添加一个index.jsp页面,内容随便写点什么,然后像3.4节那样启动应用,这时你会发现控制台上有输出如下信息:


这说明Web应用已经成功启动。此时我们在浏览器中输入http://localhost:8080/osgiapp回车后,即可看到我们新建的index.jsp页面中的内容。如下所示:      

   

本篇内容至此为止,相关的后续篇章敬请关注!--- 潇湘振宇 2010-06-20


============================

备注:因为这几天没有网络,所以就这篇先写在了文档里了,然后粘贴过来,没想到粘贴后的布局有点乱,而且不太好调。现附上原文档如下:

基于OSGi的Web应用开发系列三(搭建项目框架)


posted on 2010-06-20 22:09 潇湘振宇 阅读(10684) 评论(2)  编辑  收藏 所属分类: OSGi系列

Feedback

# re: 基于OSGi的Web应用开发系列三(搭建项目框架) 2010-06-22 10:33 爱之谷
Require-Bundle也尽量少用,如果自己清楚自己的项目用到哪几些包,那就直接Import-Package那些包好了  回复  更多评论
  

# re: 基于OSGi的Web应用开发系列三(搭建项目框架) 2015-07-06 17:35 Wick
JXADF(http://osgi.jxtech.net)是一个基于OSGi的企业级快速开发平台,官网的在线演示、丰富文档、免费插件下载,都相当不错。  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: