【问题标题】:Updating files inside an existing WAR file更新现有 WAR 文件中的文件
【发布时间】:2010-02-05 20:03:12
【问题描述】:

我正在尝试使用 ANT WAR 任务更新现有 WAR 文件中的文件。 我需要用我的 HDD 中的新文件替换 WAR 文件夹中的一组 xml 文件。

<war destfile="myApp.war" update="true" >
    <zipfileset dir="<PathToStubsFolderOnHDD>" includes="**/*.xml" prefix="<PathToStubsFolderInWAR>"/>
</war>

如果原始 WAR 没有同名的 xml,这可以正常工作。但是,如果原始 WAR 包含同名的 xml; WAR 任务不会使用 HDD 中的文件更新它们。

ANT WAR 任务文档如下:

更新 |指示是否更新或覆盖已存在的目标文件。默认为“假”。
重复 |发现重复文件时的行为。有效值为“add”、“preserve”和“fail”。默认值为“添加”。

如果我使用 update="false";原始 WAR 中的所有其他文件都被删除,只存储新的 xml。

使用 duplicate="add" 也没有任何效果。

关于如何实现这一点有什么建议吗??

【问题讨论】:

    标签: ant


    【解决方案1】:

    似乎使用update=true 选项,war 文件比您要更新的文件更新。 Someone 建议应用带有 '0' 的 touch 任务来解决问题。

    zip 任务仅检查您希望添加到现有 zip 的源文件是否比 zip 更新。一种解决方法是在添加之前&lt;touch millis="0" /&gt; zip 文件。

    或者你也可以reverse stuff:

    在对 XML 文件执行 war 任务之前执行 touch 会成功 工作。

    【讨论】:

      【解决方案2】:

      谢谢艾托!

      这是完整的 ANT 脚本:

      <target name = "UpdateWARWithStubs"
          description="Updates WAR file with files from Stub folder">
      
          <!-- Use touch to set modification time of all stubs to current time. This will force war task to update stub files inside the war -->
          <tstamp> <format property="touch.time" pattern="MM/dd/yyyy hh:mm aa"/>  </tstamp>
          <touch datetime="${touch.time}">
              <fileset dir="${path.to.stubs.on.hdd}" />
          </touch>
      
          <war destfile="myApp.war" update="true">
              <zipfileset dir="${path.to.stubs.on.hdd}"  prefix="${path.to.stubs.in.war}"/>
          </war>
      </target>
      

      【讨论】:

      • 上例中定义的要更新的war文件的war路径在哪里?
      • 您可以将路径硬编码为 destfile="path/for/war/myApp.war" 或更好地从属性 ${path.for.war}/${file.name 中读取值。战争}
      • 我正在尝试做类似的事情。 &lt;war destfile="myApp.war" update="true"&gt; &lt;zipfileset dir="${path.to.stubs.on.hdd}" prefix="${path.to.stubs.in.war}"/&gt;
      • 堆栈溢出不会让我编辑以前的评论...我正在尝试做类似的事情。 &lt;war destfile="myApp.war" update="true" needxmlfile="false"&gt; &lt;zipfileset dir="C:\" includes="extrafile.txt" prefix=""/&gt;&lt;/war&gt; 我的额外文件在战争中,但 WEB-INF 不见了。我在没有 needxmlfile 的情况下尝试过,但构建失败。有什么建议吗?
      【解决方案3】:

      这是我替换 zip(.war) 文件中现有文件的解决方案。初始状态是我有 build.xml 为 Tomcat6 服务器编译和打包 mywebapp.war。 Tomcat7 服务器需要在 war 文件中进行微小的配置更改。

      • 项目子文件夹 web 和 webT7 是 CVS 控制的文件夹,我不想无缘无故地触摸时间戳。以下技巧可以完成这项工作。
      • 像往常一样编译和创建 web/WEB-INF/lib/mywebapp.jar 文件
      • target "war" 从 web 文件夹创建 tomcat6 存档
      • webT7 子文件夹中的特定文件很少,例如 META-INF/context.xml 和 WEB-INF/web.xml,我必须为每个 tomcat 版本进行一些修改。
      • 创建 mywebapp.war.zip 文件的副本
      • 将文件从 webT7 子文件夹复制到新的构建临时文件夹,不要使用 preservelastmodified 属性!!!这为每个文件提供了一个新的时间戳,因此无需单独的触摸命令即可对其进行触摸。
      • 故障安全触摸新 zip 以放置过去的时间戳,这可确保 zip 更新正常工作。
      • 使用 zip 任务更新 mywebapp.war_T7.zip 内容,它应该替换现有文件,因为我们在没有保留原始时间戳的情况下复制了它们。

      我将 webT7 内容复制到临时构建文件夹的原因是内容管理系统。我不想无缘无故地更改原始存储库文件的时间戳。无论我使用什么 Tomcat 目标,其他所有 compile、jar、war 目标始终相同。

      如前所述,Zip update="true" 属性不会替换文件,仅当 zip 的文件比我们提供的文件旧时才会更新。如果我有 web/config.jsp(2013-01-21 14:01:01) 和 webT7/config.jsp(2012-12-21 15:02:03) 文件,这可能会带来问题。文件未被替换。

      来自 build.xml 文件的片段

      <target name="war" depends="compile,jar" description="Create a .war file">
          <delete file="${name}.war.zip" />
          <zip destfile="${name}.war.zip"
              basedir="./web/"
              excludes="
                  **/CVS*
                  "
          />
      </target>
      
      <target name="warT7" depends="war" description="Create a .war file for Tomcat7">
          <delete dir="${build}" />
          <mkdir dir="${build}" />
      
          <delete file="${name}.war_T7.zip" />
          <copy file="${name}.war.zip" 
            tofile="${name}.war_T7.zip" overwrite="true" preservelastmodified="true"
          />      
      
          <copy todir="${build}" overwrite="true">
            <fileset dir="./webT7" />
          </copy>
      
          <touch datetime="01/31/1981 01:00:00 AM" file="${name}.war_T7.zip" />
          <zip destfile="${name}.war_T7.zip" update="true">
            <zipfileset dir="${build}"  prefix="" />
          </zip>
          <delete dir="${build}" />
      </target>
      

      【讨论】:

        【解决方案4】:

        也许最简单的方法是将战争爆炸到一个临时目录,进行更改然后重建战争。不可否认,不好。

        【讨论】:

          【解决方案5】:

          这两种触摸选项都不适合我。由 ant 脚本中的 maven 工件创建的原始战争文件可能与此有关。最终将war文件重新打包到一个临时文件中并像这样覆盖原始的war文件:

          <target name="update-properties">
              <war destfile="target/${war.name}temp" needxmlfile='false'>
                  <zipfileset src="target/${war.name}" includes="**/*" 
                                excludes="${path.to.properties.in.war}" />
                  <zipfileset file="${path.to.new.properties}"  
                                fullpath="${path.to.properties.in.war}" />
              </war>
              <move file="target/${local.war.name}temp" tofile="target/${local.war.name}"/>
              <delete file="target/${local.war.name}temp"/>
          </target>
          

          其中${path.to.properties.in.war} 可以类似于"WEB-INF/classes/META-INF/spring/database.properties"

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-10-26
            • 1970-01-01
            • 1970-01-01
            • 2012-08-02
            相关资源
            最近更新 更多