substring a variable in pom.xml - java

Is it possible (and how) to substring a variable in the pom.xml, or the properties that uses this variable?
My scenario:
I have a swing application that shows a kind of version in its footer.
This version is read from a properties file.
The properties file only have a reference for a maven variable, as:
version=${git.branch}
In my pom.xml, a have a plugin that looks for the branch name, and write it in the "git.branch" variable.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>pl.project13.maven</groupId>
<artifactId>git-commit-id-plugin</artifactId>
<version>2.2.2</version>
<configuration>
<dotGitDirectory>${project.basedir}/../.git</dotGitDirectory>
<injectAllReactorProjects>true</injectAllReactorProjects>
</configuration>
<executions>
<execution>
<id>get-the-git-infos</id>
<goals>
<goal>revision</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/version.properties</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<excludes>
<exclude>**/version.properties</exclude>
</excludes>
</resource>
</resources>
</build>
But now we are using a prefix for the branch names, and this prefix shouldn't be deployed with the application version.
I had branches like:
v123
v124
v125
Now I have branches like:
b_04_v123
b_04_v124
And i want maven to get only the value "v124" of the string "b_04_v123", the prefix is fixed, aways like "b_NN_".
NOTE: No, it's not possible to change the branch names, as other departments uses them with scripts and automation.

you can use org.codehaus.groovy.maven plugin:
<plugin>
<groupId>org.codehaus.groovy.maven</groupId>
<artifactId>gmaven-plugin</artifactId>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<source>
System.setProperty("version2","${version}".replace('b_04_', ''))
</source>
</configuration>
</execution>
</executions>
</plugin>
and now you can use version2 :
version=${version2}

I solved it inside the java code, I already had a code reading the properties file, just added the substring there.
It isn't a beautiful maven solution, but worked. I could have done this since the beginning.
But, if someone could tell how can I substring a variable in my pom.xml it would be great, although I don't need it anymore (or with the same urgency) I'm still curious.

I stumbled upon this question myself and the other provided answers did not work for me. So I created my own Maven plugin.
It can search and replace other variables or normal text using regular expressions and so create a new variable.
For your case it would be something like this:
<plugin>
<groupId>io.github.1tchy</groupId>
<artifactId>variable-search-replace-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<goals>
<goal>replace</goal>
</goals>
<configuration>
<text>${git.branch}</text>
<search>^b_\d\d_</search>
<variableName>old.version</variableName>
</configuration>
</execution>
</executions>
</plugin>
Then you can simply use it as a normal property: version=${old.version}
The plugin can also define a replacement text: check out its documentation!

Related

Maven artifact plugin buildinfo remove unwanted buildinfo information

On using
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-artifact-plugin</artifactId>
<version>3.3.0</version>
</plugin>
I am able to get buildinfo file generated as following as per https://reproducible-builds.org/docs/jvm/
#### Work In Progress ####
buildinfo.version=1.0-SNAPSHOT
name=name
group-id=groupId
artifact-id=artifact id
version=version
**source information**
no scm configured in pom.xml
**build instructions**
build-tool=mvn
**effective build environment information**
java.version=11
java.vendor=Oracle corporation
os.name=Linux
**Maven rebuild instructions and effective environment:**
mvn.version=Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
**output**
outputs.0.filename=pom file name
outputs.0.length=<1234
outputs.0.checksums.sha512=abcd
Apart from name,group-id,artifact-id and version, i don't want other properties to be generated in that file. how can i configure that using maven-artifact-plugin
I have checked the doc https://maven.apache.org/plugins/maven-artifact-plugin/plugin-info.html, couldn't find example of removing unwanted information from getting generated in that file.
You may achieve something similar using maven-resources-plugin and optionally copy-rename-maven-plugin (if you need to get particular name of buildinfo file)
contents of .buildinfo:
name=${project.name}
group-id=${project.groupId}
artifact-id=${project.artifactId}
version=${project.version}
maven configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<id>build-info</id>
<goals>
<goal>resources</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>${project.basedir}</directory>
<filtering>true</filtering>
<includes>
<include>.buildinfo</include>
</includes>
</resource>
</resources>
<outputDirectory>${project.build.directory}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.coderplus.maven.plugins</groupId>
<artifactId>copy-rename-maven-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<id>copy-and-rename-file</id>
<phase>process-resources</phase>
<goals>
<goal>rename</goal>
</goals>
<configuration>
<sourceFile>${project.build.directory}/.buildinfo</sourceFile>
<destinationFile>${project.build.directory}/${project.artifactId}-${project.version}.buildinfo</destinationFile>
</configuration>
</execution>
</executions>
</plugin>

Setting properties in maven using gmaven plugin

I am using gmaven-plugin to convert the maven user.name property to lower case. The plugin configuration looks like this
<plugin>
<groupId>org.codehaus.groovy.maven</groupId>
<artifactId>gmaven-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<source>
import org.apache.commons.lang.StringUtils
project.properties["user.id"] =
StringUtils.lowerCase(project.properties["user.name"])
</source>
</configuration>
</execution>
</executions>
</plugin>
I also have maven resource resource plugin to copy some resources in a filtered mode. The entry in the manifest.yml is :
- name: ${user.id}-app
And the maven resource plugin configuration is below
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-context</id>
<phase>package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.basedir}/target</outputDirectory>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<include>manifest.yml</include>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
My problem is that the ${user.id} is not replaced in the manifest.yml file. Any idea what I am doing wrong ?
The same property is also used in other plugins like maven-antrun-plugin and build-helper-maven-plugin etc. Everything gets replaced fine there. And things also work fine if I directly use ${user.name} in the manifest.yml or any other user defined property in the POM file. But I am looking for lower case. ${user.name} returns upper case.
Any other approache to achieve the same is also welcome.

How to make Eclipse recognize folders as "code folders" when a project is imported?

I have a Maven Java project in which I added to the pom:
<build>
....
<plugin>
<!-- adding second test source directory (just for integration tests) -->
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>${plugin.build-helper-maven-plugin.version}</version>
<executions>
<execution>
<id>add-integration-test-source</id>
<phase>generate-test-sources</phase>
<goals>
<goal>add-test-source</goal>
</goals>
<configuration>
<sources>
<source>src/integration-test/java</source>
</sources>
</configuration>
</execution>
<execution>
<id>add-integration-test-resource</id>
<phase>generate-test-resources</phase>
<goals>
<goal>add-test-resource</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>src/integration-test/resources</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</build>
InteliJ recognized my java and resource folders under integration-test as a code folder, but Eclipse doesn't.
Is there any way that eclipse adds these folders as code folders when the project is imported?
Try to right click on your folder in Project Explorer select Build Path option in context menu and later click Use as Source Folder in menu which appears after choosing Build Path.
I suggest not using your own directory layout with Maven since this will cause many problems and you always have to configure around it. Just stick to the standard.
Separate integration tests and unit tests not by their source folders, but by their name.
Put all tests in src/test/java. You don't have to configure anything at this point, this path is taken by default.
Call integration tests IT*.java and unit tests UT*.java.
They can be run separately because maven-surefire-plugin executes unit tests and maven-failsafe-plugin executed integration tests. You can define filename patterns for identifying the test classes.
You could also create profiles for running only UTs or only ITs.
<project>
<!-- ... -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.13</version>
<configuration>
<includes>
<include>**/UT*.java</include>
</includes>
<excludes>
<exclude>**/IT*.java</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.18</version>
<configuration>
<includes>
<include>**/IT*.java</include>
</includes>
</configuration>
<executions>
<execution>
<id>failsafe-integration-tests</id>
<phase>integration-test</phase>
<goals>
<goal>integration-test</goal>
</goals>
</execution>
</executions>
</plugin>
Further reading: http://tomaszdziurko.pl/2013/01/running-unit-tests-integration-tests-separately-maven-testng/
There is also a interesting article about the correct usage of integration tests here: http://zeroturnaround.com/rebellabs/the-correct-way-to-use-integration-tests-in-your-build-process/

Maven executes only few tests [duplicate]

This question already has answers here:
Maven does not find JUnit tests to run
(34 answers)
Closed 7 years ago.
I am struggeling on executing all junit tests by maven test.
There are 57 Tests in 10 classes but somehow maven executes only
12 Tests in 6 classes. The ignored classes are in the same folder
as another class, beeing executed.
However, when run my test source folter as JUnit Test it does execute
all tests.
Funny thing: I copied a test, which had been executed, but even the copy
is ignored by maven.
Any help will be appreciated.
<build>
<sourceDirectory>src</sourceDirectory>
<testSourceDirectory>test</testSourceDirectory>
<resources>
<resource>
<directory>resources</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>2.3</version>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.5.201505241946</version>
<configuration>
<append>true</append>
</configuration>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>post-unit-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
By default, it is the maven-surefire-plugin that is launching the unit test and it includes only classes whose name match a condition.
This is documented in the includes parameter of this plugin. Quoting:
When not specified and when the test parameter is not specified, the default includes will be
<includes>
<include>**/Test*.java</include>
<include>**/*Test.java</include>
<include>**/*TestCase.java</include>
</includes>
Therefore, you need to make sure all of your test classes respect this naming convention. Otherwise, you need to override this default configuration to suit your needs.

Howto copy README.md into src/main/resources?

I want to show README.md file like help page in my web application. In order not to create duplicate, I need to copy by mvn from project path into resources.
How can I do so?
Any idea?
I have tried:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.3</version>
<configuration>
<!-- this is important -->
<overwrite>true</overwrite>
<!-- target -->
<outputDirectory>${basedir}/target/classes</outputDirectory>
<resources>
<resource>
<!-- source -->
<directory>/</directory>
<include>
<filter>**/README.md</filter>
</include>
</resource>
</resources>
</configuration>
</plugin>
The simplest solution would be to move the appropriate file(s) to src/main/resources folder whereas the second solution could be like this:
<build>
<resources>
<resource>
<directory>${project.basedir}</directory>
<includes>
<include>README.md</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
No need for maven-resources-plugin to be configured this can be handled by the usual life cylcle and resource handling. The only thing you might need to adapt is the folder where the README.md is located. If you like having filtering you need to add the <filtering>true</filtering> part as well.
Copying something via Maven during the build into src/** is in general a bad idea, cause those folders are controled by version control systems which will result in uncommitted changes which you don't like to have.
Note: It would be wise to check for up-to-date versions of plugins (cause 2.3 is of 2008!). The list of the current plugin versions can be found here: http://maven.apache.org/plugins/
This works for me in one of my projects:
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>validate</phase>
<!-- when to execute copy operation -->
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>${basedir}/pathTo.MD</directory>
</resource>
</resources>
<overwrite>true</overwrite>
<outputDirectory>${project.build.directory}/${project.build.finalName}/classes</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
I see that i have the phase and the goal extra from your version. I also used variables for the output location.
I would recommend you to be more equal to this example: http://maven.apache.org/plugins/maven-resources-plugin/examples/copy-resources.html
With "more equal" I mean like using <executions> tag.
You can of course leave out things like <id> and filtering.
The following worked fine for me:
<project>
...
<build>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
<executions>
<execution>
<id>myID</id>
<!-- here the phase you need -->
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target/extra-resources</outputDirectory>
<overwrite>true</overwrite>
<resources>
<resource>
<directory>src</directory>
<!-- Details about filtering: http://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html -->
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
...
</build>
...
</project>

Categories

Resources