使用struts的多模块,还是使用独立的webapp?

04-12-09 stephen


产品关系如下

有一个类似EJB server的服务器,提供一种树形结构数据的存储功能。
这个服务器的功能提供了一套基于SOAp的api库,现在是打包为一个 xxx-api.jar。

在这个服务器的基础上,现在要实现几种不同的基于web的应用
(这几种应用的数据模型都可以抽象为一个树形结构)。
称这几个应用为:app1, app2, app3。现在采用 struts 1.1 来实现web部分。
由于这几个不同应用都是基于 xxx-api.jar 来实现功能的,
并且使用相同的一个配置文件 xxx-api.ini,这个配置文件用来指明 服务器的连接方式。
所以现在采用struts的多模块来实现。

现在的公司是一个软件提供商,希望软件能尽量产品化,就是希望一次发布能用在多个地方,
而不希望为每一个客户做一次重复的工作。
要达到产品化的目标,最好是能做到 3 个app能独立测试,独立发布,独立升级。
当然是尽量独立,而不是完全的独立。

但是仔细考虑之后,采用struts的多模块来做存在如下的问题,没能实现上述的目标。

1.现在 app1, app2, app3 是分布有 3 个人进行开发的。
  基本上,这几个app不是同时进行开发的。
  现在已经完成了app1,并且已经测试并发布了。正在做app2和app3。
  大概半年之后可能对app1会做一些新的功能,到时会以一个新的版本发布。
  而app2和app3做第二次新功能开发的时间还没确定,因为现在正在做第一次的开发。
  总之一句话,就是基本上不可能同时对这3个app进行新功能开发。

2.内部有一个基本的发布流程。
  首先有开发人员开发,然后由测试组进行打包,并测试,
  由测试组确认没有问题了,就把这个包发布出去。
  已经发布的包不能随便更改,如果要更改,一定要重新测试。
  就是如果一个包已经发布了,如果要往这个包里面再添加一些新的文件进去,
  那么按通常的做法,测试组需要对被新加入的文件影响的所有功能再做一次测试,
  然后再一次发布。

3.由于上述原因的存在,考虑如下的情况:
  app2和app3开发完成之后,如果发布呢?由如下的两个可能方法:
  1) 重新编译包括 app1 在内的所有程序,
     然后让测试组重新测试一次包括 app1 的功能在内的所有功能,
     做一个完整的包括 app1,app2,app3在内的所有功能的包。
  2) 只把 app2 和 app3 各自相关的文件单独打一个 app2.tar 和 app3.tar。
     安装的时候,先安装 app1,然后到 app1 的安装目录把这两个 tar 包解开。
     测试的时候可以就按这种方法来安装,然后只测试app2和app3的新功能,不测试app1。
     因为可以认为把app2.tar 和 app3.tar 解压到app1的安装目录是不会影响app1的功能的。

  对比这两中做法,第一个方法太浪费测试组的工作,
  因为这样就把测试之前对app1的测试工作浪费了。
  而第二个做法,把app2.tar 和 app3.tar 解压到 app1 的安装目录真的会不影响app1的功能吗?
  这里存在疑问。因为如果3个app之间共享了一些文件的话,那么开发app2 和 app3 的时候,
  就不能修改这些共享的文件,否则到时打包app2.tar 和 app3.tar 的时候,
  就需要把这些最新的共享的文件带上,安装的时候就会覆盖了原来 app1 的同名文件。
  这种情况下,完全不测试app1可靠吗?
  同样地,半年之后,对app1做新功能的时候,也不能修改这些共享文件,否则遇到同样的问题。

  这些共享的文件包括:xxx-api.jar,strtus的库文件,3个app之间有一些共用的java类,
  比如工具类,记录登录用户信息的类。

  暂时假设这个 xxx-api.jar 比较稳定,短期内不用做升级。

  如果半年之后对app1做新功能的时候,struts 2.0已经出来了,并且有很大的功能改进,
  到时候如果希望把app1的程序升级到 struts 2.0上面去,那么这个时候就比较麻烦。
  基本上是不能这样做。

4.为了避免上述的问题,考虑采用如下的做法
  1) 每个 app1 都做为单独的 struts 的 application。
     每个app自己带一套库(包括xxx-api.jar, struts.jar,...),3个app之间只共享配置文件。
  2) 为了能共享 xxx-api.ini 这个配置文件可以设立一个 appcommon 模块。
     3个app直接读取 appcommon 目录里面的 xxx-api.ini 配置信息。
     经过试验,在webapps目录下的各个app是可以通过java代码相互访问的。
     比如目录结构如下
     
webapps
|-- app1
|   `-- WEB-INF
|-- app2
|   `-- WEB-INF
|-- app3
|   `-- WEB-INF
`-- appcommon
    `-- WEB-INF
        `-- xxx-api.ini

app1 里面可以通过 
servlet.getServletContext().getRealPath("/") + "../appcommon/WEB-INF/xxx-api.ini"
来访问这个配置文件。

  3) 3个app之间有一些共用的java类,比如工具类,记录登录用户信息的类。
     把这些类打包成一个独立的 appcommon.jar 提供给3个app。

  采用这种方法,基本上可以做到独立测试,独立发布,独立升级。
  采用这种方法的一个坏处是,3个app各自带了一套库,增加了安装文件的大小。
  欢迎大家讨论。




<p class="indent">

stephen
2004-12-09 13:39

这里把struts多模块下的目录结构也画出来,看起来比较清楚。

webapps
`-- app
    `-- WEB-INF
        |-- pages
        |   |-- app1
        |   |-- app2
        |   |-- app3
        |   `-- error.jsp
        |-- classes
        |   |-- app1
        |   |-- app2
        |   |-- app3
        |   `-- common
        `-- xxx-api.ini


<p class="indent">


aill
2004-12-20 16:20

期待高手解答

banq
2004-12-21 14:23

是采取楼主最后的方案:3个app各自带了一套库,增加了安装文件的大小。

为减少安装文件,实现下列步骤:
1. 将三个app打包在一个ear中
2. 将三个app中公用的库放到ear包中。
3. 注意设定三个app的MANIFEST.MF

这样,整个ear包就很小了,只有一套公用库。