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

我使用Maven2将configuration文件和各种文档从开发环境复制到dev-server目录。 奇怪的是,Maven在这个任务上似乎并不强大。

一些选项:

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

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

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

  • 构造一个types为zip的工件,以及通常是jartypes的POM的“main”工件,然后将该工件从资源库解压到目标目录中。

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

  • Maven Assembly插件 – 但是这似乎需要大量的手动定义,当我想简单地和“常规”地做事时。

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

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

  • maven-dependency-plugin副本 ,如下所述。

所有这些似乎是不必要的特别的:Maven应该擅长做这些标准的任务,没有大惊小怪。

任何build议?

不要回避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> 

在回答这个问题时,我将重点放在你所问的细节上。 如何复制文件? 这个问题和variables名称引起了我一个更大的问题:“是否有更好的方法来处理服务器configuration? 使用Maven作为构build系统来生成可部署的工件,然后在单独的模块或其他地方完成这些自定义。 如果您共享了更多的构build环境,可能会有更好的方法 – 有一些插件可以configuration多个服务器。 你可以附上一个在服务器根目录下解压缩的程序集吗? 你在用什么服务器?

再次,我相信有一个更好的方法。

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

Maven依赖项插件为我节省了大量的时间和ant的工作:

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

依赖:复制文档,并有像解压缩更有用的目标。

为了复制文件使用:

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

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

对于一个简单的复制任务,我可以推荐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>部分replace为

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

此外,如果需要,您可以在多个阶段中指定多个执行,第二个目标是“重命名”,只是按照说明进行,而其他configuration保持不变。 有关更多用法示例,请参阅Usage-Page 。

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

上面的ant解决scheme最容易configuration,但是我使用Atlassian的maven-upload-plugin运行。 我无法find好的文档,下面是我如何使用它:

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

上面引用的variables“$ {jboss.host}”在我的〜/ .m2 / settings.xml中定义,并使用mavenconfiguration文件激活。 这个解决scheme并不局限于JBoss,这正是我命名我的variables。 我有一个开发,testing和生活的configuration文件。 所以要将我的耳朵上传到testing环境中的jboss实例,我将执行:

 mvn upload:upload -P test 

这是一个来自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> ... 

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

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

`

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

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

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

那么,maven在做细粒度的任务上应该不会很好,它不是像bash或ant这样的脚本语言,而是声明性的 – 你说 – 我需要一场战争,或者一个耳朵,然后你明白了。 但是,如果您需要自定义战争或耳朵应该看起来像内部,你有一个问题。 它不是像ant一样的程序,而是声明性的。 这在一开始就有一些优点,最后可能会有很多弊端。

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

但是,如果你在你的poms和less量定制插件上付出了足够的努力,你将会得到一个比ant更好的构build环境(当然,取决于你的项目,但是对于更大的项目来说它变得越来越真实)。

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

复制任意文件的通用方法是利用Maven Wagon运输抽象。 它可以通过fileHTTPFTPSCPWebDAV等协议处理不同的目的地。

有几个插件提供了通过使用Wagon来复制文件的function。 最值得注意的是:

  • 开箱即用的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并且创build了校验和文件。 这是没有办法的。

  • 货车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

上面的例子在命令行中传递了插件参数。 或者,可以直接在POMconfiguration插件。 然后调用就像mvn deploy:deploy-file@configured-execution-id 。 或者它可以被绑定到特定的构build阶段。

请注意,对于像SCP这样的协议,您需要在您的POM定义一个扩展名:

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

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

总结上面的一些好的答案: Maven的目的是构build模块,并将结果复制到Maven存储库。 任何将模块复制到部署/安装程序input目录都必须在Maven核心function的上下文之外进行,例如使用Ant / Maven copy命令。

我能够为这个答案拼凑一些不同的来源:

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

从〜/ .ms / settings.xml

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

然后运行命令:(-X用于debugging)

mvn -X upload:upload