Eden

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

问题描述

在eclipse中,maven项目依靠M2Eclipse插件与eclipse进行集成.这会带来如下问题:

  1. 在eclipse中,如果A项目依赖B项目,而A和B都在当前的workspace中,则eclipse会自动,在A项目的.settings\org.eclipse.wst.common.component文件中增加dependent-module标签,指向B项目
  2. eclipse在将项目发布到TOMCAT上时, 会根据.settings\org.eclipse.wst.common.component文件中的dependent-module标签指定的module,去当前的workspace中找到对应的项目,例如上面提到的B项目.在发布A到tomcat上时,eclipse找到B项目,并将其打包成jar,发布到TOMCAT上A项目根路径下WEB-INF/lib中.这本身是件好事情,一旦你修改了B,eclipse会自动提示你A项目需要同步,在同步TOMCAT的同时,eclipse就会自动重新打包B项目.这样,你在B项目的任何修改,不用install或者deploy,A就能立刻获取最新的B项目jar包
  3. 但是,eclipse在将项目打包时,直接使用了项目在workspace中的名称.例如B项目,打包成 B.jar.而maven项目打包时默认会带上版本号和分类,例如 B-0.0.1.jar,即使指定了finalname,也仅仅对package后生成的jar包有效.如果A项目依赖B项目的0.0.1版本.那通过eclipse自动打包到lib下的是B.jar,而通过maven package到lib下的却是B-0.0.1.jar,此时finalname属性不生效.
  4. 在一个war项目依赖另一个war项目时,我们希望mvn package可以合并依赖的war项目中的所有文件,当然,maven可以轻易做到.但是eclipse却没这个功能.例如war项目A,依赖war项目B,则我们在eclipse中运行A项目时,自然希望能自动把B项目中的文件合并过来,一起发布到TOMCAT上运行.由于eclipse没这个功能,比较便捷的方式是,让maven 的package直接打包到eclipse发布到TOMCAT上的那个目录,这样就可以手动合并几个war项目.但是,这就遭遇了上述的问题,由于eclipse自己发布和jar和maven打包时copy的同样一个jar,名字不同.造成会在lib下出现重复的jar.例如: B.jar和B-0.0.1.jar.如果这些jar里又包含了会被引用的spring的配置文件,那就会造成配置文件的重复引用.而spring规定某些bean是不能重复出现的.

解决方案

将上述问题分为2部分来解决:

  • 如何在eclipse中方便的合并war,并将合并后的目录发布到TOMCAT上进行运行
    1. 使用maven的package功能,在package时,maven会先把所有war的内容都copy到一个目录下(由maven-war-plugin的webappDirectory属性控制),然后进行压缩.将这个目录路径指向eclipse在TOMCAT上发布项目的路径,就可以合并war内容.要实现这个目标需要做如下改动:
      1. 增加profile,因为只有在开发环境下才需要这样做
      2. 在开发环境的profile里改变webappDirectory属性,由于每个人的TOMCAT路径都不同,所以不适合放在POM.XML里设置.改为个人本地的profiles.xml,在profiles.xml里的profile中,覆盖默认webappDirectory属性
      3. 缺点:
        1. 需要每个人都在本地复制一个profiles.xml,并手动修改其中属性指向TOMCAT上项目路径
        2. 一旦依赖的WAR有新版本,需要手动执行一下package.而如果依赖的war项目的新版本中删除了某些文件,则需要执行TOMCAT的clean,然后再执行maven的package,否则被删除的文件还会继续在本地存在
        3. 合并后的所有文件都在TOMCAT下,开发人员需要在eclipse里新建一个folder,并link到那个路径下,方能看到合并后的所有内容,而link的folder并不会自动刷新,需要频繁的F5
        4. 存在重复jar问题
    2. 不改变package时的webappDirectory属性,直接将默认的webappDirectory路径引入.settings\org.eclipse.wst.common.component,例如<wb-resource deploy-path="/" source-path="/target/uum"/>,同时引入.settings\.jsdtscope,<classpathentry kind="src" path="target/uum"/>.这样,package后,eclipse会自动发现有内容变化,并提示同步到TOMCAT上.
      1. 缺点"
        1. 需要修改POM.XML,避免每次clean时,把target/uum这个目录给删除了.一旦被删除,eclipse就会自动更新org.eclipse.wst.common.component文件,去掉之前手动加的一行.
        2. .settings\.jsdtscope 配置的src,一旦有文件修改,会被eclipse自动感知,遗憾的是,eclipse只会感知在jsdtscope文件第一行配置的src,现在有2行src,例如<classpathentry kind="src" path="src/main/webapp"/>和<classpathentry kind="src" path="target/uum"/>
        3. 一旦有新的更新,package后不能直接生效,每次必须clean TOMCAT,然后重新发布
        4. 如果依赖的war发布了新版本,删除了某些文件,则需要手动清理target/uum,再package,然后再发布到TOMCAT.因为这个路径现在不在TOMCAT上,执行clean TOMCAT无法清理
        5. 存在重复jar问题
  • 如何避免jar重复
    1. 如果采用上述a方案,开发一个maven插件,@phase package,在maven package之后执行,清理一下重复的jar即可
    2. 如果采用b方案,目前尚未有比较好的解决方案,期待大家集思广益
posted on 2010-11-02 10:49  Johney  阅读(6613)  评论(1编辑  收藏  举报