代码之家  ›  专栏  ›  技术社区  ›  Joshua Fox

使用Maven复制文件的最佳实践

  •  171
  • Joshua Fox  · 技术社区  · 16 年前

    我有配置文件和各种文档,希望使用maven2从dev环境复制到dev服务器目录。奇怪的是,马文似乎不擅长这项工作。


    一些选项:

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

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

    • 使用Ant插件执行 复制 从蚂蚁。

    • 构造类型的工件 拉链 在POM的“主要”人工制品旁边,通常是 罐子 然后 打开 从存储库到目标目录的工件。

    • Maven资源 插件,如下所述。

    • Maven程序集插件——但当我想简单地“常规地”做事情时,这似乎需要很多手工定义。

    • This page 甚至展示了如何建立一个插件来进行复制!

    • Maven上传 插件,如下所述。

    • Maven依赖插件 具有 复制 ,如下所述。


    所有这些看起来都是不必要的即兴创作:Maven应该擅长于完成这些标准任务,而不必大惊小怪。

    有什么建议吗?

    13 回复  |  直到 6 年前
        1
  •  108
  •   Tim O'Brien    16 年前

    不要回避Antrun插件。仅仅因为一些人倾向于认为蚂蚁和小牛是对立的,他们不是。如果需要执行一些不可避免的一次性自定义,请使用复制任务:

    <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
  •  128
  •   Kijewski Jim    10 年前
    <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
  •  26
  •   Alexander Drobyshevsky    9 年前

    要复制文件,请使用:

            <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>  
    
        4
  •  18
  •   DwB    7 年前

    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。

        5
  •  14
  •   james.garriss Pavel    7 年前

    对于简单的复制任务,我可以推荐 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找到这个限制。)

        6
  •  6
  •   Kyle Renfro    16 年前

    上面的Ant解决方案是最容易配置的,但是我很幸运地使用了Atlassian的Maven上载插件。我找不到好的文档,以下是我如何使用它:

    <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 ~/.m2/settings.xml中定义,并使用maven概要文件激活。这个解决方案不局限于JBoss,这就是我命名变量的地方。我有一个dev、test和live的配置文件。因此,要将EAR上载到测试环境中的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/

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

    `

        7
  •  5
  •   siddhadev    16 年前

    好吧,Maven不应该擅长做精细的任务,它不是bash或ant这样的脚本语言,它是声明性的——你说——我需要一场战争,或者一只耳朵,然后你就明白了。然而,如果你需要定制战争或耳朵内部的样子,你会遇到一个问题。它不像Ant那样是程序性的,而是声明性的。 这在开始时有一些好处,在结束时可能有很多缺点。

    我想最初的概念是有很好的插件,即“只是工作”,但现实情况是不同的,如果你做非标准的东西。

    但是,如果您在POM中投入足够的精力和很少的定制插件,您将获得一个更好的构建环境,例如,使用Ant(当然取决于您的项目,但对于更大的项目,它会变得越来越真实)。

        8
  •  4
  •   azerole    12 年前

    我有很好的经验 copy-maven-plugin . 与Maven资源插件相比,它有一个更方便和简洁的语法。

        9
  •  4
  •   ᄂ ᄀ    6 年前

    复制任意文件的一般方法是利用 Maven Wagon 运输抽象。它可以通过协议处理不同的目的地,比如 file , HTTP , FTP , SCP WebDAV .

    有几个插件提供了通过使用 Wagon . 最值得注意的是:

    • 箱外 Maven Deploy Plugin

      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 Plugin

      使用 upload-single goal :

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

      使用 Wagon Maven Plugin 因为复制是直接的,似乎是最通用的。


    在上面的例子中 <url> 可以是任何受支持的协议。查看现有列表 Wagon Providers . 例如

    • 正在本地复制文件: file:///copy/to
    • 正在将文件复制到运行的远程主机 SSH : scp://host:22/copy/to


    上面的例子在命令行中传递插件参数。或者,插件可以直接在 POM . 然后调用将简单地像 mvn deploy:deploy-file@configured-execution-id . 或者它可以绑定到特定的构建阶段。


    请注意,对于类似的协议 单链构象多态性 要工作,您需要在 聚甲醛 :

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


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

        10
  •  3
  •   whaley    16 年前

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

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

        11
  •  2
  •   Brian Fox    16 年前

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

        12
  •  1
  •   Gerold Broser    7 年前

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

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

        13
  •  -1
  •   Alireza    7 年前

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