206

我有配置文件和各种文档,我想使用 Maven2 从开发环境复制到 dev-server 目录。奇怪的是,Maven 似乎不擅长这项任务。

一些选项:

  • 在 Maven 中简单使用复制任务
<copy file="src/main/resources/config.properties" tofile="${project.server.config}/config.properties"/>
  • 使用 Ant 插件从 Ant 执行复制

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

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

    • Maven Assembly 插件——但这似乎需要大量手动定义,当我想简单而“传统地”做事时。

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

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

    • maven-dependency-plugincopy,如下所述。


所有这些似乎都是不必要的临时性:Maven 应该擅长于完成这些标准任务而无需大惊小怪。

有什么建议吗?

4

14 回答 14

141
<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>
于 2009-08-10T11:26:02.483 回答
128

不要回避 Antrun 插件。只是因为有些人倾向于认为 Ant 和 Maven 是对立的,但事实并非如此。如果您需要执行一些不可避免的一次性定制,请使用复制任务:

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

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

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

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

同样,我确信有更好的方法。

于 2009-03-29T05:51:02.977 回答
54

为了复制文件使用:

        <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>  
于 2015-08-18T19:52:55.360 回答
23

对于简单的复制任务,我可以推荐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>

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

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

于 2016-04-19T01:07:13.210 回答
21

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>

dependency:copy是 documentend,并且有更多有用的目标,例如 unpack。

于 2011-11-18T10:59:06.950 回答
7

上面的 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>

上面引用的“${jboss.host}”等变量在我的 ~/.m2/settings.xml 中定义,并使用 maven 配置文件激活。此解决方案不受 JBoss 限制,这正是我命名变量的名称。我有一个用于开发、测试和实时的配置文件。因此,要将我的耳朵上传到测试环境中的 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://root@localhost</jboss.deployUrl>
    </properties>
  </profile>
  <profile>
    <id>test</id>
    <properties>
       <jboss.host>testserver</jboss.host>
       ...

注意:有这个插件的 Atlassian maven repo 在这里:https ://maven.atlassian.com/public/

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

`

于 2009-04-23T14:04:41.863 回答
6

好吧,maven 不应该擅长做细粒度的任务,它不是像 bash 或 ant 这样的脚本语言,它是一种声明性的语言——你说——我需要一场战争,或者一个耳朵,你明白了。但是,如果您需要自定义战争或耳朵的内部外观,您就有问题了。它不像蚂蚁那样是程序性的,而是声明性的。这在开始时有一些优点,最后可能会有很多缺点。

我猜最初的概念是拥有优秀的插件,“只是工作”,但如果你做非标准的东西,现实就不同了。

但是,如果您在 pom 和少量自定义插件上投入足够的精力,您将获得一个更好的构建环境,例如使用 ant (当然取决于您的项目,但对于更大的项目来说越来越真实)。

于 2009-03-06T11:28:30.347 回答
4

我在copy-maven-plugin方面有很好的经验。与 maven-resources-plugin 相比,它具有更方便和简洁的语法。

于 2013-03-29T16:04:51.100 回答
4

复制任意文件的通用方法是利用Maven Wagon传输抽象。file它可以通过、HTTP、或FTP等协议处理各种目的地。SCPWebDAV

有一些插件提供了通过使用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并创建了校验和文件。没有办法解决这个问题。

  • Wagon 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>中可以是任何支持的协议。请参阅现有Wagon 供应商列表。例如

  • 在本地复制文件:file:///copy/to
  • 将文件复制到正在运行的远程主机SSHscp://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>


如果您要复制到的目标需要身份验证,则可以通过Serversettings提供凭据。repositoryId/serverId传递给插件必须与设置中定义的服务器匹配。

于 2017-02-26T12:38:43.160 回答
3

我只能假设您的 ${project.server.config} 属性是自定义定义的并且在标准目录布局之外。

如果是这样,那么我会使用复制任务。

于 2009-02-25T17:11:32.470 回答
2

另一种方法是使用程序集插件将这些东西捆绑到一个工件中。然后您可以使用依赖插件将这些文件解压缩到您想要的位置。依赖插件中也有复制目标来复制工件。

于 2009-03-31T17:07:41.133 回答
1

我能够为这个答案拼凑出许多不同的来源:

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

于 2010-10-12T09:02:25.990 回答
0

如果有人想完全控制源路径和目标路径的路径,那么使用maven-antrun-plugin'scopy任务是最好的选择。这种方法将允许您在系统上的任何路径之间进行复制,而不管相关路径是否在mvn项目中。我有一种情况,我不得不做一些不寻常的事情,比如将生成的源文件从target目录复制回src目录以进行进一步处理。在我的情况下,这是唯一没有大惊小怪的选择。示例代码片段来自pom.xml

<plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-antrun-plugin</artifactId>
        <version>1.8</version>
        <executions>
            <execution>
                <phase>process-resources</phase>
                <configuration>
                <tasks>
                    <copy file="${basedir}/target/myome/minifyJsSrcDir/myome.min.js" todir="${basedir}/src/main/webapp/app/minifyJsSrcDir"/>
                </tasks>
                </configuration>
                <goals>
                <goal>run</goal>
                </goals>
            </execution>
        </executions>
</plugin>
于 2021-02-02T12:05:30.013 回答
-1

总结上面的一些很好的答案:Maven旨在构建模块并将结果复制到 Maven 存储库。任何将模块复制到部署/安装程序输入目录都必须在 Maven 核心功能的上下文之外完成,例如使用 Ant/Maven复制命令。

于 2009-08-13T10:53:25.523 回答