Рекомендации по копированию файлов с помощью Maven

У меня есть файлы конфигурации и различные документы, которые я хочу скопировать из среды dev в каталог dev-server с помощью Maven2. Как ни странно, Maven не кажется сильным в этой задаче.


Некоторые из вариантов:

  • простое использование скопировать задача в Maven

<copy file="src/main/resources/config.properties" tofile="${project.server.config}/config.properties"/>

  • используйте плагин Ant для выполнения скопировать от Муравей.

  • построить артефакт типа zip, наряду с" основным " артефактом POM, который обычно имеет тип jar, потом распакуйте этот артефакт из хранилища в целевой каталог.

  • maven-ресурсы плагин, как указано ниже.

  • Maven Assembly plugin -- но это, похоже, требует много ручных определений, когда я хочу что-то делать просто и "условно"."

  • на этой странице даже показывает, как построить плагин для копирования!

  • maven-загрузить плагин, как указано ниже.

  • в Maven-зависимость-плагин С скопировать, как указано ниже.


Все это кажется ненужным ad hoc: Maven должен преуспеть в выполнении этих стандартных задач без суеты и беспокоиться.

какие-либо советы?

13 ответов


Не уклоняйтесь от плагина Antrun. Просто потому, что некоторые люди склонны думать, что Ant и Maven находится в оппозиции, они не. Используйте задачу копирования, если вам нужно выполнить некоторые неизбежные одноразовые настройки:

<project>
  [...]
  <build>
    <plugins>
      [...]
      <plugin>
        <artifactId>maven-antrun-plugin</artifactId>
        <executions>
          <execution>
            <phase>deploy</phase>
            <configuration>
              <tasks>

                <!--
                  Place any Ant task here. You can add anything
                  you can add between <target> and </target> in a
                  build.xml.
                -->

              </tasks>
            </configuration>
            <goals>
              <goal>run</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
  [...]
</project>

отвечая на этот вопрос, я фокусируюсь на деталях того, что вы спросили. Как скопировать файл? Вопрос и имя переменной приводят меня к большим вопросам, таким как: "есть ли лучший способ справиться с подготовкой сервера?"Используйте Maven как система сборки для создания развертываемого артефакта, а затем выполните эти настройки либо в отдельных модулях, либо в другом месте. Если вы поделились немного больше вашей среды сборки, может быть лучший способ - есть плагины для подготовки нескольких серверов. Не могли бы вы прикрепить сборку, распаковал в корень сервера? Какой сервер вы используете?

опять же, я уверен, что есть лучший путь.


<build>
    <plugins>
        ...
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-resources-plugin</artifactId>
            <version>2.3</version>
        </plugin>
    </plugins>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include> **/*.properties</include>
            </includes>
        </resource>
    </resources>
    ...
</build>

для копирования файла используйте:

        <plugin>
            <artifactId>maven-resources-plugin</artifactId>
            <version>2.7</version>
            <executions>
                <execution>
                    <id>copy-resource-one</id>
                    <phase>install</phase>
                    <goals>
                        <goal>copy-resources</goal>
                    </goals>

                    <configuration>
                        <outputDirectory>${basedir}/destination-folder</outputDirectory>
                        <resources>
                            <resource>
                                <directory>/source-folder</directory>
                                <includes>
                                    <include>file.jar</include>
                                </includes>
                            </resource>
                        </resources>
                    </configuration>
                </execution>
           </executions>
        </plugin>

для копирования папки с подпапками используйте следующую конфигурацию:

           <configuration>
              <outputDirectory>${basedir}/target-folder</outputDirectory>
              <resources>          
                <resource>
                  <directory>/source-folder</directory>
                  <filtering>true</filtering>
                </resource>
              </resources>              
            </configuration>  

плагин зависимости maven сэкономил мне много времени, лаская с задачами ant:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>install-jar</id>
            <phase>install</phase>
            <goals>
                <goal>copy</goal>
            </goals>
            <configuration>
                <artifactItems>
                    <artifactItem>
                        <groupId>...</groupId>
                        <artifactId>...</artifactId>
                        <version>...</version>
                    </artifactItem>
                </artifactItems>
                <outputDirectory>...</outputDirectory>
                <stripVersion>true</stripVersion>
            </configuration>
        </execution>
    </executions>
</plugin>

на зависимость:копия является documentend и имеет более полезные цели, такие как распаковка.


для простой копии-задачи, которые я могу рекомендовать копировать-переименовать-Maven-плагин. Это прямо вперед и простой в использовании:

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>com.coderplus.maven.plugins</groupId>
        <artifactId>copy-rename-maven-plugin</artifactId>
        <version>1.0</version>
        <executions>
          <execution>
            <id>copy-file</id>
            <phase>generate-sources</phase>
            <goals>
              <goal>copy</goal>
            </goals>
            <configuration>
              <sourceFile>src/someDirectory/test.environment.properties</sourceFile>
              <destinationFile>target/someDir/environment.properties</destinationFile>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

Если вы хотите скопировать несколько файлов, заменить <sourceFile>...</destinationFile> часть

<fileSets>
  <fileSet>
    <sourceFile>src/someDirectory/test.environment.properties</sourceFile>
    <destinationFile>target/someDir/environment.properties</destinationFile>
  </fileSet>
  <fileSet>
    <sourceFile>src/someDirectory/test.logback.xml</sourceFile>
    <destinationFile>target/someDir/logback.xml</destinationFile>
  </fileSet>                
</fileSets>

кроме того, вы можете указать несколько исполнений в несколько этапов, если это необходимо, вторая цель - "переименовать", которая просто делает то, что она говорит, в то время как остальная часть конфигурации остается прежней. Для Больше примеров использования см. Использование-Страницы.

Примечание: этот плагин может копировать только файлы, а не каталоги. (Спасибо @Джеймс.garriss для поиска этого ограничения.)


решение ant выше проще всего настроить, но мне повезло использовать Maven-upload-plugin от Atlassian. Я не смог найти хорошую документацию, вот как я ее использую:

<build>
  <plugin>
    <groupId>com.atlassian.maven.plugins</groupId>
    <artifactId>maven-upload-plugin</artifactId>
    <version>1.1</version>
    <configuration>
       <resourceSrc>
             ${project.build.directory}/${project.build.finalName}.${project.packaging}
       </resourceSrc>
       <resourceDest>${jboss.deployDir}</resourceDest>
       <serverId>${jboss.host}</serverId>
       <url>${jboss.deployUrl}</url>
     </configuration>
  </plugin>
</build>

переменные, такие как " ${jboss.host}", упомянутые выше, определены в my ~/.м2/настройки.xml и активируются с помощью профилей maven. Это решение не ограничено JBoss, это только то, что я назвал своими переменными. У меня есть профиль для dev, test и live. Итак, чтобы загрузить мое ухо в экземпляр jboss в тестовой среде я бы выполнил:

mvn upload:upload -P test

вот снипет из настроек.XML-код:

<server>
  <id>localhost</id>
  <username>username</username>
  <password>{Pz+6YRsDJ8dUJD7XE8=} an encrypted password. Supported since maven 2.1</password>
</server>
...
<profiles>
  <profile>
    <id>dev</id>
    <properties>
      <jboss.host>localhost</jboss.host> 
      <jboss.deployDir>/opt/jboss/server/default/deploy/</jboss.deployDir>
      <jboss.deployUrl>scp://root@localhost</jboss.deployUrl>
    </properties>
  </profile>
  <profile>
    <id>test</id>
    <properties>
       <jboss.host>testserver</jboss.host>
       ...

заметки: РЕПО Atlassian maven, в котором есть этот плагин, находится здесь:https://maven.atlassian.com/public/

Я рекомендую загрузить источники и посмотреть документацию внутри, чтобы увидеть все функции, которые предоставляет плагин.

`


Ну, maven не должен быть хорош в выполнении тонких гранулированных задач, это не язык сценариев, такой как bash или ant, он довольно декларативный - вы говорите - мне нужна война или ухо, и Вы ее получите. Однако, если вам нужно настроить, как война или ухо должны выглядеть внутри, у вас есть проблема. Это просто не процедурно, как ant, а декларативно. Это имеет некоторые плюсы в начале, и может иметь много минусов в конце.

Я думаю, что первоначальная концепция должна была иметь штраф плагины, которые "просто работают", но реальность отличается, если вы делаете нестандартные вещи.

Если вы, однако, приложите достаточно усилий в своих poms и нескольких пользовательских плагинах, вы получите гораздо лучшую среду сборки, например, с ant (зависит от вашего проекта, конечно, но это становится все более и более верно для больших проектов).


У меня был очень хороший опыт работы с копировать-maven-плагин. Он имеет гораздо более удобный и лаконичный синтаксис по сравнению с Maven-resources-plugin.


Я могу только предположить, что ваши ${проект.сервер.config} свойство является чем-то пользовательским и находится вне стандартного макета каталога.

Если да, то я бы использовал задачу копирования.


общий способ копирования произвольных файлов-использовать Maven Wagon транспортная абстракция. Он может обрабатывать различные назначения через протоколы, такие как file, HTTP, FTP, SCP или WebDAV.

есть несколько плагинов, которые предоставляют возможности для копирования файлов с помощью Wagon. Наиболее примечательными являются:

  • из-из-коробки Maven Развернуть Плагин

    есть deploy-file цель. Это довольно негибко, но может выполнить свою работу.

    mvn deploy:deploy-file -Dfile=/path/to/your/file.ext -DgroupId=foo -DartifactId=bar -Dversion=1.0 -Durl=<url> -DgeneratePom=false

    существенный недостаток использования Maven Deploy Plugin это то, что он предназначен для работы с репозиториями Maven. Он предполагает определенную структуру и метаданные. Вы можете видеть, что файл помещен под foo/bar/1.0/file-1.0.ext и создаются файлы контрольной суммы. Ничего не поделаешь.

  • Универсал Maven Плагин

    использовать upload-single цель:

    mvn org.codehaus.mojo:wagon-maven-plugin:upload-single -Dwagon.fromFile=/path/to/your/file.ext -Dwagon.url=<url>

    использование Wagon Maven Plugin для копирования является простым и, кажется, наиболее универсальным.


В приведенных выше примерах <url> может иметь любой поддерживаемый протокол. См. список существующих Поставщики Фургон. Например

  • копирование файла локально:file:///copy/to
  • копирование файла удаленный хост SSH: scp://host:22/copy/to


Приведенные выше примеры передают параметры плагина в командной строке. Кроме того, плагины можно настроить непосредственно в POM. Тогда вызов будет просто похож на mvn deploy:deploy-file@configured-execution-id. Или он может быть привязан к определенной фазе построения.


Обратите внимание, что для протоколов, таких как SCP для работы вам нужно будет определить расширение в свой POM:

<build>
  [...]
  <extensions>
    <extension>
      <groupId>org.apache.maven.wagon</groupId>
      <artifactId>wagon-ssh</artifactId>
      <version>2.12</version>
    </extension>
  </extensions>


Если назначение, которое вы копируете, требует аутентификации, учетные данные могут быть предоставлены через Server настройки. repositoryId/serverId переданные Плагины должны соответствовать серверу, определенному в настройках.


другой способ-связать эти вещи в артефакт с помощью плагина сборки. Затем вы можете использовать плагин зависимостей, чтобы распаковать эти файлы, где вы хотите. Существуют также цели копирования в плагине зависимостей для копирования артефактов.


я смог собрать воедино несколько разных источников для этого ответа:

...
<repository>
    <id>atlassian</id>
    <name>Atlassian Repo</name>
    <url>https://maven.atlassian.com/content/repositories/atlassian-public</url>
</repository>
...
<dependency>
    <groupId>com.atlassian.maven.plugins</groupId>
    <artifactId>maven-upload-plugin</artifactId>
    <version>1.1</version>
</dependency>
...
<plugin>
    <groupId>com.atlassian.maven.plugins</groupId>
    <artifactId>maven-upload-plugin</artifactId>
    <version>1.1</version>
    <configuration>
        <serverId>jira-repo</serverId>
        <resourceSrc>
            ${project.build.directory}/${project.build.finalName}.${project.packaging}
        </resourceSrc>
        <resourceDest>opt/jira/webapps</resourceDest> <!-- note: no leading slash -->
        <url>scp://root@jira</url>
    </configuration>
</plugin>
...

С ~/.m2/settings.xml:

...
<servers>
  <server>
    <id>jira-repo</id>
    <username>myusername</username>
    <password>mypassword</password>
  </server>
</servers>
...

затем выполните команду: (- X для отладки)

mvn -X upload:upload


обобщить некоторые ответы выше: Maven предназначен для создания модулей и копирования результатов в репозиторий Maven. Любое копирование модулей в каталог развертывания / установки-ввода должно выполняться вне контекста основных функций Maven, например, с помощью Ant/Maven скопировать.