Maven artifact plugin buildinfo remove unwanted buildinfo information - java

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>

Related

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.

Create and install de-lomboked source jar in maven

Disclaimer: I have solved this problem and am documenting the solution for the world to know.
How do I create and install a *-sources.jar containing "delomboked" source code in maven?
By default, The maven-source-plugin creates a sources jar without delomboking the source files, which causes projects that depend on the library binaries to complain about mismatching source files.
TL;DR (explained beneath)
Add the following plugins configuration to your plugins configuration in the project.build element of your pom.xml
<project>
...
<build>
<plugins>
...
<plugin>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-maven-plugin</artifactId>
<version>1.18.0.0</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>delombok</goal>
</goals>
</execution>
</executions>
<configuration>
<sourceDirectory>src/main/java</sourceDirectory>
<outputDirectory>${project.build.directory}/delombok</outputDirectory>
<addOutputDirectory>false</addOutputDirectory>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>copy-to-lombok-build</id>
<phase>process-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
</resource>
</resources>
<outputDirectory>${project.build.directory}/delombok</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>generate-delomboked-sources-jar</id>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<jar destfile="${project.build.directory}/${project.build.finalName}-sources.jar"
basedir="${project.build.directory}/delombok"/>
</target>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
<executions>
<execution>
<id>install-source-jar</id>
<goals>
<goal>install-file</goal>
</goals>
<phase>install</phase>
<configuration>
<file>${project.build.directory}/${project.build.finalName}-sources.jar</file>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<classifier>sources</classifier>
<generatePom>true</generatePom>
<pomFile>${project.basedir}/pom.xml</pomFile>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Explanation
lombok-maven-plugin will enable you to delombok the source code (${project.basedir}/src/main/java) and place it in the target directory (${project.build.directory}/delombok). Usually this will place the code in the ${project.build.directory}/generated-sources/delombok folder, but because Intellij automatically considers this additional source-code, duplicate code errors will occur when developing your library, in order to stop this, just specify a non-default target directory (in this case just outside of the generated-sources dir).
maven-resources-plugin is necessary in order to also copy resources from the standard ${project.basedir}/src/main/resources directory. If there are any other non-standard resource directories in your project, you should configure them in the resources section for this plugin.
maven-antrun-plugin is used instead of the maven-source-plugin because you cannot specify a custom source directory in the latter. The jar task points to our custom "generated-sources" and produces the standard-named sources jar.
maven-install-plugin install-file goal is used because you cannot attach jars using the install goal. We can hack a solution by manually installing a file using the install-file goal with a classifier of sources.
I hope this helps others who are on struggle street like I was with this problem.
The following solution is based on the one offered above but improves it by using the build-helper plugin to attach the generated delomboked source jar instead of using install-file. This has the benefit that the normal maven install and deploy phases correctly handle the generated file just as they would if the sources plugin had been used.
<project>
...
<build>
<plugins>
...
<plugin>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-maven-plugin</artifactId>
<version>1.18.12.0</version>
<executions>
<execution>
<id>delombok-sources</id>
<phase>generate-sources</phase>
<goals>
<goal>delombok</goal>
</goals>
<configuration>
<sourceDirectory>src/main/java</sourceDirectory>
<outputDirectory>${project.build.directory}/delombok</outputDirectory>
<addOutputDirectory>false</addOutputDirectory>
<encoding>UTF-8</encoding>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>generate-delomboked-sources-jar</id>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<jar destfile="${project.build.directory}/${project.build.finalName}-sources.jar"
basedir="${project.build.directory}/delombok"/>
</target>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>attach-delomboked-sources-jar</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>${project.build.directory}/${project.build.finalName}-sources.jar</file>
<type>jar</type>
<classifier>sources</classifier>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Would like to point out that a profile can also be used (to get around the build source directory being un-customizable). The solution is described at https://sudonull.com/post/1197-Lombok-sourcesjar-and-convenient-debug
Add the following to the pom.xml
properties:
<origSourceDir>${project.basedir}/src/main/java</origSourceDir>
<sourceDir>${origSourceDir}</sourceDir>
<delombokedSourceDir>${project.build.directory}/delombok</delombokedSourceDir>
</properties>
Profile and build section changes:
<profiles>
<profile>
<id>build</id>
<properties>
<sourceDir>${delombokedSourceDir}</sourceDir>
</properties>
</profile>
</profiles>
<build>
<sourceDirectory>${sourceDir}</sourceDirectory>
<plugins>
<plugin>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-maven-plugin</artifactId>
<version>1.18.20.0</version>
<executions>
<execution>
<id>delombok</id>
<phase>generate-sources</phase>
<goals>
<goal>delombok</goal>
</goals>
<configuration>
<addOutputDirectory>false</addOutputDirectory>
<sourceDirectory>${origSourceDir}</sourceDirectory>
<outputDirectory>${delombokedSourceDir}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
Execute with mvn clean install -Pbuild
This should solve the "Library source does not match the bytecode for class" error in IntelliJ and allow seamless debugging in most cases.
Ref: "Delombok plugin + profile in maven"
Both of the answers are flawed for multi-module projects or pure pom projects, because there are no sources, so you will have to create an empty directory, and it'll produce an empty .jar.
There is a simple (but a bit more complex) way to achieve functionality you want: make your own Maven Plugin.
Sounds overly complicated, but we can re-use maven-sources-plugin and with MOJO's inheritance update necessary parts:
import java.util.List;
import java.util.stream.Collectors;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.source.SourceJarNoForkMojo;
import org.apache.maven.project.MavenProject;
/**
* This goal bundles all the sources into a jar archive, but uses delomboked sources.
*/
#Mojo(name = "jar-no-fork", defaultPhase = LifecyclePhase.VERIFY, threadSafe = true)
public class EnhancedSourceJarNoForkMojo extends SourceJarNoForkMojo {
#Parameter(property = "<some-prefix>.useDelombokSources", defaultValue = "true")
protected boolean useDelombokSources;
#Parameter(property = "<some-prefix>.delombokSourcesLocation", defaultValue = "delombok")
protected String delombokSourcesLocation;
#Override
protected List<String> getSources(MavenProject p) {
// if user doesn't want delomboked sources, use default algorithm
List<String> sources = super.getSources(p);
if (!useDelombokSources) {
return sources;
}
// typically, sources' list will contain: [src/main/java, target/generated_sources].
// replace src/main/java if it's present with delombok-generated sources
String target = p.getBuild().getDirectory();
return super.getSources(p)
.stream()
.map(s -> s.endsWith("java") ? String.format("%s/%s", target, delombokSourcesLocation) : s)
.collect(Collectors.toList());
}
}
Gist with pom.xml routine is available here.

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!

Configure javafx-maven-plugin to create jar file without version number

I cannot stop my javafx-maven-plugin to insert the version number into the jars file name. I tried to set finalName to "${pom.artifactId}" but that doesn't help.
What can I do?
<plugin>
<groupId>com.zenjava</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>8.1.4</version>
<configuration>
<mainClass>application.Main</mainClass>
<jfxAppOutputDir>${project.build.directory}</jfxAppOutputDir>
<finalName>${pom.artifactId}</finalName>
</configuration>
<executions>
<execution>
<id>create-jfxjar</id>
<phase>package</phase>
<goals>
<goal>build-jar</goal>
</goals>
</execution>
</executions>
</plugin>
It is an old question, but:
1.Insert final jar Name in this way:
<build>
<finalName>your.customname.without.versionNumber</finalName>
2.Edit javafx-maven-plugin configuration, add this inside the configuration tag:
<jfxMainAppJarName>${project.build.finalName}.jar</jfxMainAppJarName>
The complete configuration should looks like this:
<plugin>
<groupId>com.zenjava</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>8.8.3</version>
<configuration>
<jfxMainAppJarName>${project.build.finalName}.jar</jfxMainAppJarName>
<mainClass>com.my.amazingapp.MainClassName</mainClass>
<vendor>The Tiger Programmer</vendor>
<manifestAttributes>
<developer>Me</developer>
<contact>me#company.com</contact>
</manifestAttributes>
</configuration>
</plugin>
Now if your finalName is "MyAmazingProject", after you run mvn clean jfx:jar you will find a file MyAmazingProject.jar under
/target/jfx/app/MyAmazingProject.jar
This jar is a executable jar with Manifest Info.

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/

Categories

Resources