I am trying to use the maven-replacer-plugin to replace tokens in my web.xml when it is built in the WAR file but not in the source, which would remove the tokens for subsequent builds and show the file as changed relative to the version control repository.
Currently, I am only able to change the file in the source, which does not meet my requirement:
<plugin>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>replacer</artifactId>
<version>1.5.2</version>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>replace</goal>
</goals>
</execution>
</executions>
<configuration>
<file>${project.basedir}/src/main/webapp/WEB-INF/web.xml</file>
<replacements>
<replacement>
<token>##sec.level##</token>
<value>local</value>
</replacement>
</replacements>
</configuration>
</plugin>
Question: How can I run the replacer to only change the file in the WAR package while leaving the source unchanged for subsequent builds?
You can use the exploded goal of the maven-war-plugin to get to a temporary folder (like whatever created under target actually) the exploded version of what would later on be part of the final war file, then execute the replacer plugin on this file (a safe copy, not in conflict with other plugins consuming the file).
This approach is actually also documented by the official replacer plugin doc
That is, having a similar configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<useCache>true</useCache>
</configuration>
<executions>
<execution>
<id>prepare-war</id>
<phase>prepare-package</phase>
<goals>
<goal>exploded</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>replacer</artifactId>
<version>1.5.2</version>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>replace</goal>
</goals>
</execution>
</executions>
<configuration>
<file>${project.build.directory}/${project.build.finalName}/WEB-INF/web.xml</file>
<token>##sec.level##</token>
<value>local</value>
</configuration>
</plugin>
Note: the replacer documentation also suggests to use the useCache option which should prevent the plugin to override what the exploded goal previously created. However, the option doesn't really suit this purpose.
Similarly, the following approach would instead work according to my tests:
Use the exploded goal of the maven-war-plugin to create a temporary copy of the future war file in a <war_name>-tmp directory under target: that's not an issue, whatever is under target is supposed to be discarded via a clean command anyway
Configure the replacer plugin to replace that copy of the web.xml file
Configure the default war goal using its webXml option to point to that web.xml file for its final war file
The following would apply the approach described above:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<!-- explode the future war content for pre-package processing -->
<id>prepare-war</id>
<phase>prepare-package</phase>
<goals>
<goal>exploded</goal>
</goals>
<configuration>
<webappDirectory>${project.build.directory}/${project.build.finalName}-tmp</webappDirectory>
</configuration>
</execution>
<execution>
<!-- use the same execution id to further configure the default binding and execution -->
<id>default-war</id>
<phase>package</phase>
<goals>
<goal>war</goal>
</goals>
<configuration>
<!-- during the package phase, use the processed web.xml file -->
<webXml>${project.build.directory}/${project.build.finalName}-tmp/WEB-INF/web.xml</webXml>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>replacer</artifactId>
<version>1.5.2</version>
<executions>
<execution>
<!-- apply pre-package processing on web resources -->
<id>process-web-resources</id>
<phase>prepare-package</phase>
<goals>
<goal>replace</goal>
</goals>
</execution>
</executions>
<configuration>
<file>${project.build.directory}/${project.build.finalName}-tmp/WEB-INF/web.xml</file>
<token>##test##</token>
<value>local</value>
</configuration>
</plugin>
Related
I need to separate the checkstyle plugin configs for production and test source code.
I managed to do it (see the config bellow), but there is 'checkstyle-checker.xml' file which is always overriden and stays in the root of the target directory.
Is there a way to move it to /target/checkstyle directory?
Is there a way to separate it between prod and test source code?
<plugin>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>${maven-checkstyle-plugin.version}</version>
<configuration>
<encoding>${project.build.sourceEncoding}</encoding>
<consoleOutput>true</consoleOutput>
<failsOnError>true</failsOnError>
<failOnViolation>${maven-checkstyle-plugin.failOnViolation}</failOnViolation>
<logViolationsToConsole>${maven-checkstyle-plugin.logViolationsToConsole}</logViolationsToConsole>
<violationSeverity>warning</violationSeverity>
<linkXRef>true</linkXRef>
<skip>${maven-checkstyle-plugin.skip}</skip>
</configuration>
<executions>
<execution>
<id>checkstyle-validate</id>
<phase>validate</phase>
<goals>
<goal>check</goal>
</goals>
<configuration>
<sourceDirectories>${project.build.sourceDirectory}</sourceDirectories>
<includeTestSourceDirectory>false</includeTestSourceDirectory>
<configLocation>/checkstyle/checkstyle.xml</configLocation>
<outputFile>${project.build.directory}/checkstyle/checkstyle-result.xml</outputFile>
<cacheFile>${project.build.directory}/checkstyle/checkstyle-cache</cacheFile>
</configuration>
</execution>
<execution>
<id>checkstyle-validate-test</id>
<phase>validate</phase>
<goals>
<goal>check</goal>
</goals>
<configuration>
<sourceDirectories/>
<testSourceDirectories>${project.build.testSourceDirectory}</testSourceDirectories>
<includeTestSourceDirectory>true</includeTestSourceDirectory>
<configLocation>/checkstyle/checkstyle-test.xml</configLocation>
<outputFile>${project.build.directory}/checkstyle/checkstyle-result-test.xml</outputFile>
<cacheFile>${project.build.directory}/checkstyle/checkstyle-cache-test</cacheFile>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.puppycrawl.tools</groupId>
<artifactId>checkstyle</artifactId>
<version>${maven-checkstyle-plugin.checkstyle.rules.version}</version>
</dependency>
</dependencies>
</plugin>
This file appears to be generated by maven-checkstyle-plugin as seen at https://github.com/apache/maven-checkstyle-plugin/blob/6d229a74b4a7eb2efc5fce287d932f6b5c250647/src/main/java/org/apache/maven/plugins/checkstyle/exec/DefaultCheckstyleExecutor.java#L733
Looking at https://github.com/apache/maven-checkstyle-plugin/blob/6d229a74b4a7eb2efc5fce287d932f6b5c250647/src/main/java/org/apache/maven/plugins/checkstyle/exec/DefaultCheckstyleExecutor.java#L765 it appears there is no way to override it's location and it will always go into the project's build directory.
I am not sure what purpose this file plays in the work the plugin does as this is not part of the base checkstyle library.
I'm using Mockserver maven plugin to mock some requests for integration tests.
My pom.xml looks like:
...
<plugin>
<groupId>org.mock-server</groupId>
<artifactId>mockserver-maven-plugin</artifactId>
<version>5.5.1</version>
<configuration>
<serverPort>1080</serverPort>
<logLevel>DEBUG</logLevel>
<initializationClass>com.mycompany.ExampleInitializationClass</initializationClass>
</configuration>
<executions>
<execution>
<id>run-mockserver</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>stop-mockserver</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
...
Problem here is that I have to provide expectations using a class (com.mycompany.ExampleInitializationClass) and I want to provide expectations using a JSON file like described here:
http://www.mock-server.com/mock_server/initializing_expectations.html
I didn't find any way in the plugin configuration to initialize the Mockserver with the property:
-Dmockserver.initializationJsonPath
Is there any way to achieve that? Thanks in advance.
You just have to define initializationJson property specifying path to JSON file with expectations:
<plugin>
<groupId>org.mock-server</groupId>
<artifactId>mockserver-maven-plugin</artifactId>
<version>5.5.1</version>
<configuration>
<serverPort>1080</serverPort>
<logLevel>DEBUG</logLevel>
<initializationJson>expectations.json</initializationJson>
</configuration>
<executions>
...
</executions>
</plugin>
The catch here is that the file path is relative to testClasspath directory (e.g. ${project.basedir}/target/test-classes/), so you have to copy the expectation file there. You may use e.g. maven-antrun-plugin for this (as below) or
maven-resources-plugin.
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<copy file="your/expectations.json" todir="${project.basedir}/target/test-classes/"/>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
I can't seem to figure this out.
I have the following in my pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<overWriteReleases>true</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
I plan to have all the dependencies copied to target/lib directory.
Why is not doing it?
My project is evolving, so I do not want specify each individual artifact to copy. I want it to take them all, and place it into a proper place during the "package" (or compile) phase.
I get only my mainProject.jar file in the lib folder.
Please, help. What am I missing?
The correct goal for copying dependencies is copy-dependencies, not compile. Also, if you want to invoke the plugin from the command line with mvn dependency:copy, the configuration section should not be inside the executions. Here is a configuration that should work in all cases:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
</execution>
</executions>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<overWriteReleases>true</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</plugin>
As you can see, I'm running the plugin in the 'package' phase, but it also works in the 'compile' phase, unless you want to include the artifact just built by your own project.
I would like to build from a maven pom running two sequential executions of the same plugin, in the same phase differing only by a single property, which will result in two different archives being created. Since the configuration is rather complicated, I'd rather NOT copy it just to change one value, which would create a maintenance nightmare. If it was somehow possible to define such a property in the <executions> section of the plugin config, I could avoid this headache.
Question: Is this possible and if so how?
Update: Two answers have mentioned using multiple executions and one of them mentions that you can have separate configurations in each execution. But given that the majority of my configuration is constant between the two executions, can I have one configuration on the plugin level and also have configuration sections in each execution for the parts that are different?
Given the simple Maven Source Plugin configuration (as an example) you have a shared configuration across all of its executions (outside the executions element) and then a custom configuration per each execution, for the same phase, as requested by your question:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.4</version>
<configuration>
<includePom>true</includePom>
</configuration>
<executions>
<execution>
<id>test-id1</id>
<phase>verify</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<finalName>aaa</finalName>
</configuration>
</execution>
<execution>
<id>test-id2</id>
<phase>verify</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<finalName>bbb</finalName>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
The configuration entry <includePom>true</includePom> will in this case be merged with the custom configurations of each execution and as such centralize the common configuration as plugin generic configuration.
For more details on the different level of configurations, you can check official Maven documentation, here, in particular the example "Configuring compile to run twice". Further details are also available on the official POM documentation, here, Plugins section.
You need to create a different execution (still bound to the same phase)
To avoid duplication of the config, you can put the <configuration> outside the <execution> element and then in the 2 executions, you only define the property that is different.
Taken from the maven docs:
<project>
...
<build>
<plugins>
<plugin>
<artifactId>maven-myquery-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<id>execution1</id>
<phase>test</phase>
<configuration>
<url>http://www.foo.com/query</url>
<timeout>10</timeout>
<options>
<option>one</option>
<option>two</option>
<option>three</option>
</options>
</configuration>
<goals>
<goal>query</goal>
</goals>
</execution>
<execution>
<id>execution2</id>
<configuration>
<url>http://www.bar.com/query</url>
<timeout>15</timeout>
<options>
<option>four</option>
<option>five</option>
<option>six</option>
</options>
</configuration>
<goals>
<goal>query</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
You create two <execution> elements within the <plugin> declaration. Each <execution> element can have it's own <configuration> section.
I wanted to create a jar and a put in in a zip file with other config files
This worked for me
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4.1</version>
<executions>
<execution>
<id>build-jar-with_dep1</id>
<phase>package</phase>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<finalName>${buildversion}</finalName>
<finalName>finalname</finalName>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
<goals>
<goal>assembly</goal>
</goals>
</execution>
<execution>
<id>build_zip1</id>
<phase>package</phase>
<configuration>
<descriptor>src/assembly/bin.xml</descriptor>
<finalName>${buildversion}</finalName>
<finalName>finalname</finalName>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
Is there a way to have maven pad a numeric value (ex: build number) within a POM? I've been googling the topic and haven't come up with anything yet.
My use case is as follows. The maven build process is provided a build number via Jenkins which needs to be included as part of the name of the WAR that is generated. So if I provide it 12 as the build number, then I want the WAR file name to be myWar##000012.war. The ##000012 part of the name is the version identifier used by Tomcat.
The simplest solution may be to embed a scripting language in your build. For example, with Groovy, if you have a buildNumber property:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>groovy-maven-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<phase>validate</phase>
<goals><goal>execute</goal></goals>
<configuration>
<source>
project.properties['nameSuffix'] = "##" + String.format("%06d", project.properties['buildNumber'].toLong());
</source>
</configuration>
</execution>
</executions>
</plugin>
Afterwards the nameSuffix property is available to define the final name.
Alternatively, as suggested in In Maven, how can I dynamically build a property value at runtime?, use build-helper:regex-property to transform the string.
Have you tried using the maven release plugin?
Based upon #Joe suggestion I looked into the build-helper-maven-plugin and was able to come up with the following which does what I need. I wasn't able to identify how to do it all in one step, so I'm doing it in 2. The first step pads the value on the left with zeros. The second step trims the numeric value so that it is only 7 digits long. Please note that ${build.env.version} is passed in as a parameter to the maven build process and that I have defaulted it to 0 in the POM file for when it isn't passed. If you don't provide a default value then the build fails even though failOnError on set to false.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>stage1--padNumber</id>
<goals>
<goal>regex-property</goal>
</goals>
<configuration>
<name>build.env.version.padded</name>
<value>${build.env.version}</value>
<regex>^([\d]{0,})$</regex>
<replacement>000000$1</replacement>
<failIfNoMatch>false</failIfNoMatch>
<failOnError>false</failOnError>
</configuration>
</execution>
<execution>
<id>stage2--leftTrimToXcharacters</id>
<goals>
<goal>regex-property</goal>
</goals>
<configuration>
<name>build.env.version.padded</name>
<value>${build.env.version.padded}</value>
<regex>^([\d]*)([\d]{7})$</regex>
<replacement>$2</replacement>
<failIfNoMatch>false</failIfNoMatch>
<failOnError>false</failOnError>
</configuration>
</execution>
</executions>
</plugin>
Based upon #jwmajors81 suggestion, I needed to pad the major version for a specific reason...
As we were already using the build-helper-maven-plugin, it is easy enough to get the major version by using the parse-version goal of the build helper. (we only needed 3 chars):
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>parse-version</id>
<goals>
<goal>parse-version</goal>
</goals>
</execution>
<execution>
<id>stage1--padNumber</id>
<goals>
<goal>regex-property</goal>
</goals>
<configuration>
<name>build.env.version.padded</name>
<value>${parsedVersion.majorVersion}</value>
<regex>^([\d]{0,})$</regex>
<replacement>00$1</replacement>
<failIfNoMatch>false</failIfNoMatch>
<failOnError>false</failOnError>
</configuration>
</execution>
<execution>
<id>stage2--leftTrimToXcharacters</id>
<goals>
<goal>regex-property</goal>
</goals>
<configuration>
<name>build.env.version.padded</name>
<value>${build.env.version.padded}</value>
<regex>^([\d]*)([\d]{3})$</regex>
<replacement>$2</replacement>
<failIfNoMatch>false</failIfNoMatch>
<failOnError>false</failOnError>
</configuration>
</execution>
</executions>
</plugin>
Yet, in that particular case, if you also need to generate a buildNumber, buildnumber-maven-plugin may be the most straight solution:
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<version>1.4</version>
<configuration>
<format>{0, number,000000}</format>
<items>
<item>buildNumber</item>
</items>
</configuration>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>create</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<finalName>myWar##${buildNumber}</finalName>