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

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


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

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

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

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

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

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

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

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

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

  • maven-dependency-plugin с копией, как указано ниже.


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

Любые советы?

Ответ 1

Не уклоняйтесь от плагина 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 как систему сборки для создания развертываемого артефакта, а затем выполните эти настройки либо в отдельных модулях, либо где-то еще. Если вы поделились немного более сложной средой сборки, возможно, будет лучший способ - есть плагины для предоставления нескольких серверов. Не могли бы вы прикрепить сборку, которая распакована в корне сервера? Какой сервер вы используете?

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

Ответ 2

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

Ответ 3

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

        <plugin>
            <artifactId>maven-resources-plugin</artifactId>
            <version>3.1.0</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>  

Ответ 4

Плагин зависимостей 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>

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

Ответ 5

Для простых задач копирования я могу порекомендовать copy-rename-maven-plugin. Он прост в использовании и прост в использовании:

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

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

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

Ответ 6

Решение выше 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}", указанные выше, определены в моем файле ~/.m2/settings.xml и активируются с использованием профилей maven. Это решение не ограничено JBoss, это именно то, что я назвал своими переменными. У меня есть профиль для dev, test и live. Поэтому для загрузки моего уха в экземпляр jboss в тестовой среде я бы выполнил:

mvn upload:upload -P test

Вот снипета из settings.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://[email protected]</jboss.deployUrl>
    </properties>
  </profile>
  <profile>
    <id>test</id>
    <properties>
       <jboss.host>testserver</jboss.host>
       ...

Примечания: Здесь находится атласский maven-репо, в котором есть этот плагин: https://maven.atlassian.com/public/

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

`

Ответ 7

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

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

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

Ответ 8

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

Ответ 9

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

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

  • Встроенный плагин Maven Deploy

    Есть цель 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 и файлы контрольной суммы созданы. Обойти это невозможно.

  • Плагин Wagon Maven

    Используйте upload-single цель 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:[email protected]. Или это может быть связано с определенной фазой сборки.


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

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


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

Ответ 10

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

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

Ответ 11

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

Ответ 12

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

...
<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://[email protected]</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

Ответ 13

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