把原有项目添加到Maven管理时,总会出现很多莫名奇妙的问题,其中之一便是Maven默认的项目结构和自己的项目结构不一致,导致无法编译源代码,更不用说部署、运行项目了。
Java程序开发,一般使用Eclipse、MyEclipse等工具,其源码目录为src,这与Maven默认的src/main/java不同。因此,在没有额外配置的情况下,使用Maven命令无法完成代码的编译。
针对这种情况,codehaus提供了build-helper-maven-plugin插件来支持自定义的项目目录结构(相对于Maven默认目录结构来说)。
官网:http://www.mojohaus.org/build-helper-maven-plugin/
<!-- https://mvnrepository.com/artifact/org.codehaus.mojo/build-helper-maven-plugin -->
<dependency>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.0.0</version>
</dependency>
Goals 概览
- build-helper:add-source Add more source directories to the POM.
- build-helper:add-test-source Add test source directories to the POM.
- build-helper:add-resource Add more resource directories to the POM.
- build-helper:add-test-resource Add test resource directories to the POM.
- build-helper:attach-artifact Attach additional artifacts to be installed and deployed.
- build-helper:maven-version Set a property containing the current version of maven.
- build-helper:regex-property Sets a property by applying a regex replacement rule to a supplied value.
- build-helper:regex-properties Sets a property by applying a regex replacement rule to a supplied value.
- build-helper:released-version Resolve the latest released version of this project.
- build-helper:parse-version Parse the version into different properties.
- build-helper:remove-project-artifact Remove project's artifacts from local repository.
- build-helper:reserve-network-port Reserve a list of random and unused network ports.
- build-helper:local-ip Retrieve current host IP address.
- build-helper:cpu-count Retrieve number of available CPU.
- build-helper:timestamp-property Sets a property based on the current date and time.
- build-helper:uptodate-property Sets a property according to whether a file set's outputs are up to date with respect to its inputs.
- build-helper:uptodate-properties Sets multiple properties according to whether multiple file sets' outputs are up to date with respect to their inputs.
- build-helper:rootlocation Sets a property which defines the root folder of a multi module build.
<!-- 设置多个源文件夹 -->
<plugin>
<groupId>dehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.8</version>
<executions>
<!-- 添加主资源文件目录 -->
<execution>
<!--自定义名称,不可重复-->
<id>add-resource</id>
<!--指定绑定到生命周期-->
<phase>initialize</phase>
<!--指定指定的目标,可添加多个-->
<goals>
<goal>add-resource</goal>
</goals>
<configuration>
<resources>
<!--资源文件目录,可添加多个-->
<resource>
<directory>${basedir}/src/main/one</directory>
<!--是否启用变量过滤-->
<filtering>true</filtering>
<!--排除的文件,可添加多个-->
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
<resource>
<directory>${basedir}/src/main/two</directory>
<filtering>true</filtering>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
</configuration>
</execution>
<!-- 添加主源码目录 -->
<execution>
<id>add-source</id>
<phase>initialize</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${basedir}/src/main/three</source>
<source>${basedir}/src/main/four</source>
</sources>
</configuration>
</execution>
<!-- 添加测试源码目录 -->
<execution>
<id>add-test-source</id>
<phase>initialize</phase>
<goals>
<goal>add-test-source</goal>
</goals>
<configuration>
<sources>
<source>${basedir}/src/main/five</source>
<source>${basedir}/src/main/six</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
官网示例
Brief examples on how to use the Build Helper Maven Plugin's goals.
Add more source directories to your project
Use this example to add more source directories to your project, since pom.xml
only allows one source directory.
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>some directory</source>
...
</sources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Add more test source directories to your project
The same as the previous example, but this time we add more test source directories to your project.
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>add-test-source</id>
<phase>generate-test-sources</phase>
<goals>
<goal>add-test-source</goal>
</goals>
<configuration>
<sources>
<source>some directory</source>
...
</sources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Add more resource directories to your project
This example shows how to add additional resource directories to your project. Another goal called add-test-resource
can be used in a similar way to add test resources to the project.
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>add-resource</id>
<phase>generate-resources</phase>
<goals>
<goal>add-resource</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>src/my-resources</directory>
<targetPath>my-resources</targetPath>
<excludes>
<exclude>**/junk/**</exclude>
</excludes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Attach additional artifacts to your project
Typically run after antrun:run
, or another plugin, that produces files that you want to attach to the project for install and deploy.
<project>
...
<build>
<plugins>
<plugin>
<!-- add configuration for antrun or another plugin here -->
</plugin>
...
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>attach-artifacts</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>some file</file>
<type>extension of your file </type>
<classifier>optional</classifier>
</artifact>
...
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Set the current version of Maven in a property
This can be used to keep track of what version of Maven was used to build a particular artifact. For example, the following POM sets the property and then uses the property to save the Maven version to the project JAR's manifest.
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>maven-version</id>
<goals>
<goal>maven-version</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<archive>
<manifestEntries>
<Maven-Version>${maven.version}</Maven-Version>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
...
</project>
Access the parsed components of a project version
The parse-version
goal can be used to access the component parts of a version string. For example, the major version or the qualifier by themselves. Executing the following plugin configuration will parse the version of the current project and set several properties.
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>parse-version</id>
<goals>
<goal>parse-version</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
After the goal executes (by default during the validate
phase) the following properties will contain the components of the current project version.
parsedVersion.majorVersion
parsedVersion.minorVersion
parsedVersion.incrementalVersion
parsedVersion.qualifier
parsedVersion.buildNumber
Apart from the above properties the following properties will be set:
parsedVersion.nextMajorVersion
parsedVersion.nextMinorVersion
parsedVersion.nextIncrementalVersion
parsedVersion.nextBuildNumber
And another set of properties is set by using the defined formatting. See build-helper:parse-version
formattedVersion.majorVersion
formattedVersion.minorVersion
formattedVersion.incrementalVersion
formattedVersion.buildNumber
formattedVersion.nextMajorVersion
formattedVersion.nextMinorVersion
formattedVersion.nextIncrementalVersion
formattedVersion.nextBuildNumber
The property prefix parsedVersion
can be configured using the propertyPrefix
parameter.
An OSGi compatible version will also be created and made available through the property:
parsedVersion.osgiVersion
This property contains the original version string with the first instance of '-' replaced by '.' For example, 1.0.2-beta-1
will be converted to 1.0.2.beta-1
. Each occurance of a another .
will be replaced by _
cause OSGi does not allow to have more than three .
in a version.
Resolve the latest released version of a project
The released-version
goal can be used to resolve the latest released version of a project. Executing the following plugin configuration makes the latest released version of the current project available.
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>released-version</id>
<goals>
<goal>released-version</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
After the goal executes (by default during the validate
phase) the following property will be available.
releasedVersion.version
releasedVersion.majorVersion
releasedVersion.minorVersion
releasedVersion.incrementalVersion
The property prefix "releasedVersion" can be configured using the propertyPrefix
parameter. This property can become very handy if you want to provide links to download the latest version. If you have to do a site-deploy
during snapshot-development, the ${project.version} is useless.
Remove a project's artifacts from local repository
Mainly used to remove previously installed large project artifacts in the local repository before the install
phase starts. The example below removes all the project's artifacts including all versions from the local repository at the implicit package
phase. To remove only the current version, set the <removeAll>
configuration element to false
.
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>remove-old-installers</id>
<goals>
<goal>remove-project-artifact</goal>
</goals>
<configuration>
<removeAll>true</removeAll>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Reserve a list of random and unused network ports
Use this plugin to reserve a set of available unused network ports to be placed in a given property set, so that they can be inserted into other plugin configurations.
The example below shows how one can pass in random ports to Selenium server port and Tomcat http port. Useful for running multiple tests concurrently.
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>reserve-network-port</id>
<goals>
<goal>reserve-network-port</goal>
</goals>
<phase>process-resources</phase>
<configuration>
<portNames>
<portName>selenium.server.port</portName>
<portName>tomcat.http.port</portName>
</portNames>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>selenium-maven-plugin</artifactId>
<executions>
<execution>
<id>start-selenium</id>
<phase>test</phase>
<goals>
<goal>start-server</goal>
</goals>
</execution>
</executions>
<configuration>
<port>${selenium.server.port}</port>
[...]
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>tomcat-maven-plugin</artifactId>
<executions>
<execution>
<id>run-tomcat</id>
<phase>test</phase>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
<configuration>
<port>${tomcat.http.port}</port>
[...]
</configuration>
</plugin>
[...]
</plugins>
</build>
</project>
It is also possible to define port names via resource file(s). Resources in classpath are also supported (artifact with resource has to be defined in plugin dependencies section).
portNames
and urls
parameters can be combined.
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.0.0</version>
<dependencies>
<dependency>
<artifactId>jar-with-port-names.txt</artifactId>
[...]
</dependencies>
<executions>
<execution>
<id>reserve-network-port</id>
<goals>
<goal>reserve-network-port</goal>
</goals>
<phase>process-resources</phase>
<configuration>
<urls>
<url>file:///Users/kama/ws-git-codehaus/build-helper-maven-plugin/target/checkout/names1.txt</url>
<url>classpath:port-names.txt</url>
</urls>
</configuration>
</execution>
</executions>
</plugin>
[...]
</plugins>
</build>
</project>
port-names.txt:
# Selenium port name
selenium.server.port
# Tomcat port name
tomcat.http.port
Set a property by applying a regex replacement to a value
The regex-property
goal can be used to set a property to a value after regex replacement has been applied. For example, executing the following plugin configuration to set the human.version
property.
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>regex-property</id>
<goals>
<goal>regex-property</goal>
</goals>
<configuration>
<name>human.version</name>
<value>3.0.0</value>
<regex>-SNAPSHOT</regex>
<replacement> pre-release development version</replacement>
<failIfNoMatch>false</failIfNoMatch>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
After the goal executes (by default during the validate
phase) the human.version
property would have the value 1.0
if the project.version
was 1.0
but if the project version was 1.0-SNAPSHOT
then it would have the value 1.0 pre-release development version
.
To load multiple properties in one execution, use regex-properties
goal
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>regex-properties</id>
<goals>
<goal>regex-properties</goal>
</goals>
<configuration>
<regexPropertySettings>
<regexPropertySetting>
<name>human.version</name>
<value>3.0.0</value>
<regex>-SNAPSHOT</regex>
<replacement> pre-release development version</replacement>
<failIfNoMatch>false</failIfNoMatch>
</regexPropertySetting>
[....]
</regexPropertySettings>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
Set a property based on the current time and date
The timestamp-property
goal can be used to set a property to a value based on the current time and date (with an optional offset applied). For example, executing the following plugin configuration to set the next.year
property to next year.
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>timestamp-property</id>
<goals>
<goal>timestamp-property</goal>
</goals>
<configuration>
<name>next.year</name>
<pattern>yyyy</pattern>
<unit>year</unit>
<offset>+1</offset>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
After the goal executes (by default during the validate
phase) the next.year
property will have the value of next year.
The pattern
parameter accepts any valid java.text.SimpleDateFormat
format string.
The unit
will accept any of: millisecond
, second
, minute
, hour
, day
, week
, month
and year
. The offset
parameter takes integer values only and defaults to 0
.
The locale
and timeZone
parameters can be further used to control the build-time behaviour.
Retrieve current host IP address
The local-ip
goal can be used to load current host address
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>get-local-ip</id>
<goals>
<goal>local-ip</goal>
</goals>
<configuration>
<!-- if not given, 'local.ip' name is used -->
<localIpProperty>my.local.ip</localIpProperty>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
Retrieve available number of CPUs
The cpu-count
goal can be used to load number of CPU
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>get-cpu-count</id>
<goals>
<goal>cpu-count</goal>
</goals>
<configuration>
<!-- if not given, 'cpu.count' name is used -->
<cpuCount>my.cpu.count</cpuCount>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
Set a property according to whether target files are up to date with respect to their sources
'Up to date' means that the target file both exists and has a 'last modification timestamp' (java.io.File.lastModified()
) equal to or later than that of the corresponding source file(s).
Source files are computed relative to the fileset
's required directory
property. If the fileset
has an outputDirectory
property, target files are computed relative to that; otherwise, target files are also computed relative to directory
.
The fileset
element supports a mapper
, whose type
can be any of the built-in mappers flatten glob identity merge package unpackage
. Alternatively, the classname
property can specify the fully qualified name of a class that implements org.apache.maven.shared.model.fileset.mappers.FileNameMapper
.
The uptodate-property
goal can be used to set a property to a value if specified target files are up to date. For example, executing the following plugin configuration to set the obj.status
property.
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>obj-uptodate</id>
<goals>
<goal>uptodate-property</goal>
</goals>
<configuration>
<name>obj.status</name>
<value>fresh</value>
<else>stale</else>
<fileSet>
<directory>src/main/c</directory>
<outputDirectory>target/obj</outputDirectory>
<includes>
<include>mod-*/**</include>
</includes>
<excludes>
<exclude>**/*.old.*</exclude>
</excludes>
<mapper>
<type>glob</type>
<from>*.c</from>
<to>*.o</to>
</mapper>
</fileSet>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
After the goal executes (by default during the validate
phase) the obj.status
property would have the value fresh
if all target/obj/**/*.o
object files were up to date with respect to their corresponding src/main/c/mod-*/**/*.c
source files (excluding any with .old.
in the name); otherwise, the property would have the value stale
.
To set multiple properties for multiple file sets in one execution, use the uptodate-properties
goal. The upToDatePropertySetting
element supports all the configuration properties documented above for the uptodate-property
goal.
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>lib-doc-uptodate</id>
<goals>
<goal>uptodate-properties</goal>
</goals>
<configuration>
<upToDatePropertySettings>
<upToDatePropertySetting>
<name>lib.uptodate</name>
<fileSet>
<directory>target/obj</directory>
<outputDirectory>target/lib</outputDirectory>
<mapper>
<type>merge</type>
<from>*.o</from>
<to>mylibrary.so</to>
</mapper>
</fileSet>
</upToDatePropertySetting>
<upToDatePropertySetting>
<name>doc.uptodate</name>
<fileSet>
<directory>src/main/c</directory>
<outputDirectory>target/site/doc</outputDirectory>
<mapper>
<type>merge</type>
<from>*.c</from>
<to>mylibrary.html</to>
</mapper>
</fileSet>
</upToDatePropertySetting>
</upToDatePropertySettings>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
After the goal executes, the lib.uptodate
property would have the value true
if target/lib/mylibrary.so
is up to date with respect to all the target/obj/**/*.o
object files. Also, the doc.uptodate
property would have the value true
if target/site/doc/mylibrary.html
is up to date with respect to src/main/c/**/*.c
.
来源:oschina
链接:https://my.oschina.net/malixin/blog/4952860