我有使用Maven2从dev环境复制到dev-server目录的配置文件和各种文档。奇怪的是,Maven在这项任务中看起来并不强大。
一些选项:
<copy file="src/main/resources/config.properties" tofile="${project.server.config}/config.properties"/>
使用Ant插件从Ant执行 copy 。
构造一个 zip 类型的工件,以及POM的“主”工件,通常是 jar 类型,然后 unpack 该工件从存储库到目标目录。
maven-resources 插件,如下所述。
Maven程序集插件 - 但这似乎需要大量的手动定义,当我想简单地执行“常规”时。
This page甚至展示了如何构建一个插件来进行复制!
maven-upload 插件,如下所述。
maven-dependency-plugin 与 copy ,如下所述。
所有这些看起来都是不必要的:Maven应该擅长完成这些标准任务,而不用大惊小怪。
有什么建议吗?
答案 0 :(得分:131)
<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>
答案 1 :(得分:109)
不要回避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 :(得分:29)
要复制文件,请使用:
<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>
答案 3 :(得分:18)
maven依赖插件让我花了很多时间来处理蚂蚁任务:
<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是文档,并且有更多有用的目标,比如解包。
答案 4 :(得分: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>
如果您要复制多个文件,请将<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>
此外,如果需要,您可以在多个阶段指定多个执行,第二个目标是&#34;重命名&#34;,它只是执行它所说的,而其余配置保持不变。有关更多用法示例,请参阅Usage-Page。
注意:此插件只能复制文件,而不能复制目录。 (感谢@ james.garriss找到这个限制。)
答案 5 :(得分: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>
上面引用的“$ {jboss.host}”等变量在我的〜/ .m2 / settings.xml中定义,并使用maven配置文件激活。这个解决方案不仅限于JBoss,这正是我命名的变量。我有dev,test和live的个人资料。因此,为了将我的耳朵上传到测试环境中的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 repo位于:https://maven.atlassian.com/public/
我建议下载源代码并查看里面的文档,以查看该插件提供的所有功能。
`
答案 6 :(得分:5)
嗯,maven不应该做好细粒度的任务,它不是像bash或ant这样的脚本语言,而是声明性的 - 你说 - 我需要一场战争,或者一个耳朵,你得到它。但是,如果您需要自定义战争或耳朵在内部的样子,那么您就会遇到问题。它不像蚂蚁那样程序化,而是声明性的。 这在一开始就有一些优点,最终会有很多缺点。
我想最初的概念是拥有精美的插件,“只是工作”,但如果你做非标准的东西,现实是不同的。
如果你在你的poms和很少的自定义插件中投入了足够的精力,那么你将获得一个更好的构建环境,例如蚂蚁(当然取决于你的项目,但对于更大的项目它会变得越来越真实)
答案 7 :(得分:4)
我对copy-maven-plugin有很好的体验。与maven-resources-plugin相比,它具有更方便,更简洁的语法。
答案 8 :(得分:4)
复制任意文件的一般方法是利用Maven Wagon传输抽象。它可以通过file
,HTTP
,FTP
,SCP
或WebDAV
等协议处理各种目的地。
有一些插件提供了通过Wagon
复制文件的功能。最值得注意的是:
有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
下,并创建了校验和文件。没有办法解决这个问题。
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
一样。或者它可以绑定到特定的构建阶段。
请注意,要使SCP
等协议生效,您需要在POM
中定义一个扩展程序:
<build>
[...]
<extensions>
<extension>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-ssh</artifactId>
<version>2.12</version>
</extension>
</extensions>
如果要复制的目标位置需要身份验证,则可以通过Server
settings提供凭据。传递给插件的repositoryId
/ serverId
必须与设置中定义的服务器匹配。
答案 9 :(得分:3)
我只能假设您的$ {project.server.config}属性是自定义的,并且不在标准目录布局中。
如果是,那么我将使用复制任务。
答案 10 :(得分:2)
另一种方法是使用程序集插件将这些东西捆绑到工件中。然后,您可以使用依赖项插件将这些文件解压缩到您想要的位置。依赖插件中还有复制目标来复制工件。
答案 11 :(得分: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
答案 12 :(得分:0)
如果有人想要完全控制源路径和目标路径,那么使用 maven-antrun-plugin
的 copy
任务是最好的选择。这种方法将允许您在系统上的任何路径之间进行复制,而不管相关路径是否在 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>
答案 13 :(得分:-1)
总结一些上面的好答案: Maven 旨在构建模块并将结果复制到Maven存储库。将模块复制到部署/安装程序输入目录必须在Maven核心功能的上下文之外完成,例如,使用Ant / Maven 复制命令。