Setting properties in maven using gmaven plugin - java

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.

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>

substring a variable in pom.xml

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!

Additional resources directories for images in Maven site

For a Maven site, the standard image directory is src/site/resources/images.
Unfortunately, my asciidoc editor copies images to src/site/asciidoc/images. Can I somehow add this directory to the site resources (as in the Maven resources plugin)?
To copy all resources to an outputDirectory, you can simply specify following in your pom.xml-
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
<executions>
<execution>
<id>copy-resources</id>
<!-- here the phase you need -->
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/src/site/resources/images</outputDirectory>
<resources>
<resource>
<directory>src/non-packaged-resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
Sources - Example from the plugin itself.

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/

Specify common resources in a multi-module maven project

Is there any way to share resources between modules of a parent project in Maven? For example, I would like to specify one log4j.properties file for all the modules in a multi-module Maven project.
Generally, I use Eclipse IDE to create the parent project by choosing a general project and then convert it to a Maven project by specifying a packaging of pom. This creates a "clean" project structure without src and etc. folders. I wonder where such a shared resource should be put in this case.
EDIT1: I would like to put the common resources in the parent project.
I'd create one additional "base" module (project), packaging "jar", that contains the common resources in src/main/resources. Then I'd make the other modules depend on that project. Now they see the common resources on their classpaths.
Antoher possibility is to use a remote resource bundle. You would be able to configure it in the parent project. In this example I wanted to copy some files just for tests. If you use this you will need to create the bundle in another project.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-remote-resources-plugin</artifactId>
<version>1.5</version>
<configuration>
<resourceBundles>
<resourceBundle>es.sca:myBundle:1.0.0</resourceBundle>
</resourceBundles>
<attachToMain>false</attachToMain>
<attachToTest>true</attachToTest>
<appendedResourcesDirectory>${basedir}/src/test/resources</appendedResourcesDirectory>
</configuration>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
</execution>
</executions>
</plugin>
Another way, put in your project root pom:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<!-- don't propagate to child poms -->
<!-- this will only execute in root pom -->
<inherited>false</inherited>
<configuration>
<descriptors>
<descriptor>assembly.xml</descriptor>
</descriptors>
<!-- don't add classifier -->
<appendAssemblyId>false</appendAssemblyId>
</configuration>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugins>
And example of assembly.xml
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>resources</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>${project.basedir}/resources/</directory>
<outputDirectory/>
<useDefaultExcludes>true</useDefaultExcludes>
<includes>
<include>**</include>
</includes>
</fileSet>
</fileSets>
</assembly>
Assembly plugin will generate artifact and attach it to current reactor, so it will be installed and deployed.
No you can use it as standard dependency event in the same pom.
Important is to trigger assembly (proper phase) before another plugin which will use generated artifact.
Eg. You can have in your root pom, bellow configuration will be propagated to all your module:
<plugin>
<artifactId>some-maven-plugin</artifactId>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>goal</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>your.project.groupid</groupId>
<artifactI>your.project.artifactId</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</plugin>
You can see this method in project:
https://github.com/s4u/pgp-keys-map resources directory is shared by all module.
Yes, it seems as a possible solution. But I was interested whether it
is possible to specify these resources in the parent project (without
introducing additional module) since the parent project specifies all
the common dependencies and Maven configurations for the child
modules, I think that the parent project is the most suitable place
also for the common resources.
In case of packaging type pom , when goal package specified to manage your shared resources, just add next (check folders) into build section of pom file :
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-config-files</id>
<phase>package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/logconfig</outputDirectory>
<resources>
<resource>
<filtering>false</filtering>
<directory>${project.basedir}/src/main/resources</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
I think you can just add the resources and/or testResources elements to your pom.
E.g. to access an additional test resource directory add:
<testResources>
<testResource>
<directory>src/test/resources</directory>
</testResource>
<testResource>
<directory>../global/src/test/resources</directory>
</testResource>
</testResources>
see Maven - Override test resource folder
I managed it to work like this:
I create a project/assembly/test/resources/META-INF/persistence.xml file, and add this to my pom.xml:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-test-persistence-xml-resources</id>
<phase>process-test-sources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>src/</outputDirectory>
<resources>
<resource>
<directory>${project.parent.basedir}/assembly/</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>

Categories

Resources