使用Maven复制文件的最佳做法

Jos*_*Fox 183 build-process maven-2 release-management maven

我有配置文件和各种文档,我想使用Maven2从开发环境复制到dev-server目录.奇怪的是,Maven在这项任务中看起来并不强大.


一些选项:

  • 在Maven中简单使用复制任务

__CODE__

  • 使用Ant插件从Ant 执行复制.

  • 构造一个zip类型的工件,以及POM的"主"工件(通常是jar类型),然后将该工件从存储库解压缩到目标目录中.

  • maven-resources插件,如下所述.

  • Maven Assembly插件 - 但是当我想简单地"按常规"做事时,这似乎需要大量的手动定义.

  • 这个页面甚至展示了如何构建一个进行复制的插件!

  • maven-upload插件,如下所述.

  • 带有副本的maven-dependency-plugin,如下所述.


所有这些看起来都是不必要的:Maven应该擅长完成这些标准任务,而不用大惊小怪.

有什么建议?

小智 134

<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>
Run Code Online (Sandbox Code Playgroud)

  • 我曾经以为这是正确的答案……直到我意识到资源插件没有跳过配置。Antrun是必经之路。 (2认同)

Tim*_*ien 113

不要回避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>
Run Code Online (Sandbox Code Playgroud)

在回答这个问题时,我会关注你所问的细节.如何复制文件?问题和变量名称引出了一个更大的问题,例如:"有没有更好的方法来处理服务器配置?" 使用Maven作为构建系统来生成可部署工件,然后在单独的模块中或完全在其他位置执行这些自定义.如果您分享了更多的构建环境,可能有更好的方法 - 有插件来配置多个服务器.你能附加一个在服务器根目录中解压缩的程序集吗?你用的是什么服务器?

再说一遍,我确信有更好的方法.

  • @Matt是的,现在不推荐使用`task`参数([Antrun Plugin](http://maven.apache.org/plugins/maven-antrun-plugin/run-mojo.html)).你应该使用`target`代替(从1.5开始).不幸的是,有一些例子混淆了这一点; 例如`target`参数和`version` <1.5. (3认同)
  • 这怎么能成为公认的答案呢?当然应该有一个对 Maven 的更改请求,以使复制变得简单。 (3认同)

Ale*_*sky 33

要复制文件,请使用:

        <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>
Run Code Online (Sandbox Code Playgroud)

要使用子文件夹复制文件夹,请使用下一个配置:

           <configuration>
              <outputDirectory>${basedir}/target-folder</outputDirectory>
              <resources>          
                <resource>
                  <directory>/source-folder</directory>
                  <filtering>true</filtering>
                </resource>
              </resources>              
            </configuration>  
Run Code Online (Sandbox Code Playgroud)

  • [过滤](https://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html) 在 Maven 中指的是字符串插值,所以我省略了 `&lt;filtering&gt;` 以防止对例如使用`${...}` 变量的脚本文件。 (2认同)

Tir*_*res 19

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>
Run Code Online (Sandbox Code Playgroud)

依赖性:副本是documentend,并具备解压更有用的目标.

  • 我多年没有使用Ant了,我不想开始做这么简单的事情.谢谢你的回答. (3认同)

mor*_*n.c 15

对于简单的复制任务,我可以推荐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>
Run Code Online (Sandbox Code Playgroud)

如果要复制多个文件,请更换<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>
Run Code Online (Sandbox Code Playgroud)

此外,如果需要,您可以在多个阶段指定多个执行,第二个目标是"重命名",它只是执行它所说的内容,而其余配置保持不变.有关更多用法示例,请参阅Usage-Page.

注意:此插件只能复制文件,而不能复制目录.(感谢@ james.garriss找到这个限制.)

  • @james.garriss 我不知道这个限制,但不幸的是你是对的。我会将其编辑到我的答案中,以节省一些人自己找到它的时间。 (3认同)
  • 虽然我喜欢这个插件,但令人震惊的是它不能复制目录。 (2认同)

Kyl*_*fro 6

上面的ant解决方案最容易配置,但我很幸运使用了Atlassian的maven-upload-plugin.我无法找到好的文档,这是我如何使用它:

<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>
Run Code Online (Sandbox Code Playgroud)

上面引用的变量"$ {jboss.host}"在我的〜/ .m2/settings.xml中定义,并使用maven配置文件激活.这个解决方案不仅限于JBoss,这正是我命名的变量.我有dev,test和live的个人资料.所以要将我的耳朵上传到测试环境中的jboss实例,我会执行:

mvn upload:upload -P test
Run Code Online (Sandbox Code Playgroud)

这是来自settings.xml的snipet:

<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>
       ...
Run Code Online (Sandbox Code Playgroud)

注意:具有此插件的Atlassian maven repo位于:https://maven.atlassian.com/public/

我建议下载源代码并查看里面的文档以查看插件提供的所有功能.

`


sid*_*dev 5

好吧,maven不应该做好细粒度的任务,它不是像bash或ant这样的脚本语言,而是声明性的 - 你说 - 我需要一场战争,或者一个耳朵,你得到它.但是,如果您需要自定义战争或耳朵在内部的样子,那么您就会遇到问题.它不像蚂蚁那样程序化,而是声明性的.这在一开始就有一些优点,最终会有很多缺点.

我想最初的概念是拥有精美的插件,"只是工作",但如果你做非标准的东西,现实是不同的.

但是如果你在你的poms和很少的自定义插件中投入了足够的精力,那么你将获得一个更好的构建环境,例如蚂蚁(当然取决于你的项目,但对于更大的项目它会变得越来越真实).