Обновление файлов внутри существующего файла WAR

Я пытаюсь обновить файлы в существующем файле WAR с помощью задачи ANT WAR. Мне нужно заменить набор xml файлов в папке WAR с новыми с моего HDD.

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

Это отлично работает, если оригинальная WAR не имеет xmls с тем же именем. Однако если исходная WAR содержит xmls с тем же именем; WAR не обновляет файлы с жесткого диска.

Документация задачи ANT WAR читает:

обновление | указывает, следует ли обновлять или перезаписывать файл назначения, если он уже существует. Значение по умолчанию - "false".
дублировать | поведение при обнаружении дубликата файла. Допустимыми значениями являются "добавить", "сохранить" и "сбой". Значение по умолчанию - "добавить".

если я использую update = "false"; все остальные файлы в исходной WAR удаляются и сохраняются только новые xmls.

использование duplicate = "add" также не имеет никакого эффекта.

Любые предложения о том, как это можно достичь?

Ответы

Ответ 1

Похоже, что с параметром update=true военный файл новее, чем файлы, которые вы хотите обновить. Кто-то предлагает применить задачу touch с '0', чтобы обойти проблему.

Задача zip проверяется только в том случае, если исходные файлы, которые вы хотите добавить в существующий почтовый индекс, являются более поздними, чем zip. Обходной путь будет заключаться в <touch millis="0" /> zip файле перед добавлением.

Или вы можете сделать обратный материал:

Выполнение touch перед задачей war в XML файле (ых) делает это работа.

Ответ 2

Спасибо Aito!

Вот полный ANT script:

<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>

Ответ 3

Возможно, самый простой способ - взорвать войну во временный каталог, внести свои изменения, а затем перестроить войну. Нехорошо, правда.

Ответ 4

Это мое решение для замены существующих файлов в zip (.war) файле. Исходное состояние: у меня есть build.xml для компиляции и упаковки mywebapp.war для сервера Tomcat6. Для сервера Tomcat7 требуются незначительные изменения конфигурации в военном файле.

  • Вложенные папки проекта и webT7 - это папки с контролем CVS, я не хочу касаться временных меток без причины. Следующий трюк выполняет эту работу.
  • скомпилировать и создать файл web/WEB-INF/lib/mywebapp.jar, как обычно
  • target "war" создает архив tomcat6 из веб-папки
  • есть несколько конкретных файлов в подпапке webT7, таких как META-INF/context.xml и WEB-INF/web.xml. Мне нужно изменить бит для каждой версии tomcat.
  • создать копию файла mywebapp.war.zip
  • скопируйте файлы из подпапки webT7 в новую папку temp temp, не используйте атрибут saveelastmodified!!! Это дает новую временную метку для каждого файла, поэтому ее касания без отдельной команды касания.
  • отказоустойчивый сенсорный новый zip, чтобы поставить прошлую метку времени, это гарантирует, что обновление zip будет работать правильно.
  • используйте zip-задачу для обновления содержимого mywebapp.war_T7.zip, она должна заменить существующие файлы, потому что мы скопировали их, не сохраняя исходные временные метки.

Причина Я копирую содержимое webT7 в папку temp build - это системы управления контентом. Я не хочу менять временные метки исходных файлов репозитория без каких-либо причин. Все остальные компиляции, jar, военные цели всегда одинаковы независимо от того, какую цель Tomcat я использую.

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>

Ответ 5

Ни один вариант касания не работал у меня. Оригинальный файл войны, созданный артефактом maven из ant script, может иметь какое-то отношение к этому. Закончилось переупаковка файла войны во временный файл и перезапись исходного файла войны следующим образом:

<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"