In my pom file I execute a build plugin with this configuration.
Can I access customProp from inside the plugin code?
<execution>
...
<configuration>
<configOptions>
<additional-properties>useTags=true</additional-properties>
</configOptions>
<customProp>custom-value</customProp>
Asumming that you are developing the plugin...
Yes, it is possible. Check Parameters section Maven's plugin development guide.
You have to define a property in your Mojo:
#Parameter( property = "your-plugin.customProperty", defaultValue = "custom" )
private String customProperty;
If I understand you correctly, when you configure spring-boot-maven-plugin and building your application, you can access information about your application's build through BuildProperties object like -
#Autowired
BuildProperties buildProperties;
and read like -
// Artifact's name from the pom.xml file
buildProperties.getName();
// Artifact version
buildProperties.getVersion();
If predefined properties are not enough, you can pass your own properties from pom.xml file to BuildProperties
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>build-info</goal>
</goals>
<configuration>
<additionalProperties>
<java.version>${java.version}</java.version>
<some.custom.property>some value</some.custom.property>
</additionalProperties>
</configuration>
</execution>
</executions>
</plugin>
You can pass a value directly or use your custom properties defined in the <properties> section of your pom.xml and then referenced using ${property.name} placeholder.
You can access custom properties defined this way by calling buildProperties.get("property.name").
Related
I need to deploy my project into artifactory. For this purpose I use maven-assembly-plugin together with artifactory-maven-plugin
only I can use for building of mvn is this CMD (small updates are possible):
mvn -e -B -U clean deploy -DskipIntegrationTests=false -DskipCoverageReport=false -Dservice_name=sample_service
What I can not do in mvn command is update service name. It will be always "sample_service" or some other constant which represent name of service
Because I do not know name of service (there could be more services) my base part of pom.xml looks like this (artifactId is created dynamically from property service_name):
<groupId>my.group.id</groupId>
<artifactId>${service_name}</artifactId>
<version>2.0.0-SNAPSHOT</version>
The problem is that parameter -Dservice_name will always consists "underscores". Because of conventions artifact has to consists "dashes" instead of "underscores".
Is there any way (some plugin for instance) how I can do something like this?
<groupId>my.group.id</groupId>
<artifactId>${service_name}.replaceAll("_","-")</artifactId>
<version>2.0.0-SNAPSHOT</version>
In short for property service_name I need replace underscores by dashes before building of artifact.
Thanks for answers.
This cannot be done.
Properties used inside <artifactId> can only be set through the command line. You have no chance to manipulate them in Maven. The only chance I see is to change the command line, so that you do the replacement before you send the parameter to Maven.
I found a solution for my problem. But I am not sure if it is correct way how to solve it. I used plugin gmaven-plugin
<plugin>
<groupId>org.codehaus.groovy.maven</groupId>
<artifactId>gmaven-plugin</artifactId>
<executions>
<execution>
<phase>pre-clean</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<source>
project.getModel().setArtifactId(project.properties["service_name"].replaceAll('_', '-'))
project.getArtifact().setArtifactId(project.properties["service_name"].replaceAll('_', '-'))
</source>
</configuration>
</execution>
</executions>
</plugin>
After that I use maven-assembly plugin which upload data into artifactory. And this plugin read artifact id from instance "project.getArtifacts()" so I update it directly.
So I updated artifact id directly in maven instance.
As I say it is not 100 percent correct but in my case it helps
You can do this with the buildhelper plugin, it has a goal regex-property which can set a property based on an initial value (your service_name property) and a regular expression to replace with a replacement value.
Example from the usage page (adapted because the value used made no sense):
<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>${project.version}</value>
<regex>-SNAPSHOT</regex>
<replacement> pre-release development version</replacement>
<failIfNoMatch>false</failIfNoMatch>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
We are using Spring-boot to build micro-services. In my project set-up we have a common maven module named platform-boot with main class with annotation SpringBootApplication
If we want to create a new micro-service (say Service-1), we simply add a dependency of platform-boot module and provide the main-class path in pom.xml and we are good to go.
Problem is when I try to read Manifest.MF file of Service-1 by writing code in my 'main-class' in dependent module. It reads the Manifest.MF file of platform-boot.
Below is the code snippet of how I am reading Manifest.MF file in my main class.
MyMain.class.getProtectionDomain().getCodeSource().getLocation().getPath();
//Returns the path of MyMain.class which is nested jar
Please suggest a way to read the Manifest.MF file of Service-1.
PS: I want to read the Maifest.MF file to get Implementation-Version. Please suggest if any other way of getting it as well.
I found two ways to solve this problem:
We can use maven-dependency-plugin to unpack the child jar while
executing the phase prepare-package. This plug in will extract the
class file from my platform-boot jar to my Service-1.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.0.2</version>
<executions>
<execution>
<id>unpack</id>
<phase>prepare-package</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>my.platform</groupId>
<artifactId>platform-boot</artifactId>
<type>jar</type>
<overWrite>false</overWrite>
<outputDirectory>${project.build.directory}/classes</outputDirectory>
<includes>**/*.class,**/*.xml,**/*.text</includes>
<excludes>**/*test.class</excludes>
</artifactItem>
</artifactItems>
<includes>**/*.java, **/*.text</includes>
<excludes>**/*.properties</excludes>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
</configuration>
</execution>
</executions>
</plugin>
Second approach is much simpler, in spring-boot-maven-plugin add a goal
build-info. This will write a file build-info.properties in your META-INF folder and is accessible in code as below.
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>build-info</goal>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
In your main method you can get this information using the BuildProperties
bean already registered in ApplicationContext.
ApplicationContext ctx = SpringApplication.run(Application.class, args);
BuildProperties properties = ctx.getBean(BuildProperties.class);
In fact, Spring-actuator also uses this BuildProperties to get the build
information which is helpful in monitoring.
Hi could you please elaborate the need of reading your service-1manifest.mf ?
If you just want the service1 as a dependeny in your parent common module and should not conflict with your service1 bootable application , you can do generate two jars through the exec configuration in spring-boot-maven-plugin .
I spent hours on this problem, searching several Google and SO entries, I have some ideas but not getting the result.
I have a maven file that does something like this:
grab a jar containing JSON schemas, and unpack them.
Using the Maven Replacer plugin (v 1.5.3), replace a line in a schema file called “MySchema.json” as such:
”Hello” :
”HelloWorld” :
then Maven would use another plugin to compile a class called “converter.java” and runs this class to output a Java file based on “MySchema.json”. let’s call the generated Java file “MyPojo.java”.
Now, I want Maven to replace a line in “MyPojo.java”, but no matter what I do I cannot achieve this.
I tried:
include a separate replace plugin entry for step 4 after the plugin that converts schemas to Java, but ofcourse this caused Maven to complain about existing replace plugin with same artifact/group id from step 2.
Tried adding a separate execution id to the goal “replace” for second plugin, this is invalid for this plugin.
There is a parent project to my current project folder, I tried putting another replacer plugin in the parent POM and make the phase to be any of the “package”, “generate-resources”, “compile”, etc. did not work. Note: the phase for replacements inside “MySchema.json” (in my current project POM) is generate-sources.
give absolute path to the Java, it kept complaining that path does not exist. But I copied and pasted the path to the Java inside windows explorer address bar after it was generated and could read it from Windows explorer. Note that the generated Java file “MyPojo.java”, went under “target/generated-sources” which is sourced by a parent POM above this project using a Maven Helper plugin in parent POM, so this folder should be visible as a source for further compilation. That Maven Helper plugin has phase generate-sources.
Use with same result as above
In my current project (non-parent one) this is the POM code:
<build>
<!—execute a plugin grab schemas jar and unpack schemas-->
...
<plugin>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>replacer</artifactId>
<version>1.5.3</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>replace</goal>
</goals>
</execution>
</executions>
<configuration>
<includes>
<include>${project.basedir}/target/schemas/MySchema.json</include>
</includes>
<replacements>
<replacement>
<token>"Hello":</token>
<value>"Hello World":</value>
</replacement>
</replacements>
</configuration>
</plugin>
<!-- execute a Plugin for converting shcemas to POJO -->
. . .
</plugins>
</build>
</project>
You should be able to declare the plugin only once and run two replace execution at different Maven Build Lifecycle phases:
Before the Json -> POJO conversion
After the Json -> POJO conversion
So, translating that into could would result in something like:
<plugin>
<!-- (unique) plugin declaration -->
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>maven-replacer-plugin</artifactId>
<version>1.3.5</version>
<executions>
<!-- first execution: replace on json file -->
<execution>
<id>replace-for-json</id>
<phase>some-phase-before-conversion</phase>
<goals>
<goal>replace</goal>
</goals>
<configuration>
<filesToInclude>${project.basedir}/target/schemas/MySchema.json</filesToInclude>
<preserveDir>true</preserveDir>
<outputDir>target</outputDir>
<replacements>
<replacement>
<token>"Hello":</token>
<value>"Hello World (Json)":</value>
</replacement>
</replacements>
</configuration>
</execution>
<!-- second execution: replace on java file -->
<execution>
<id>replace-for-pojo</id>
<phase>some-phase-after-conversion</phase>
<goals>
<goal>replace</goal>
</goals>
<configuration>
<filesToInclude>${project.basedir}/target/generated-sources/MyPojo.java</filesToInclude>
<preserveDir>true</preserveDir>
<outputDir>target</outputDir>
<replacements>
<replacement>
<token>"Hello":</token>
<value>"Hello World (Java)":</value>
</replacement>
</replacements>
</configuration>
</execution>
</executions>
</plugin>
Source: Configuration for the maven-replacer-plugin on two separate executions
I would like to specify some system properties in my applicatio (deterined at compile time).
I am using the spring boot maven plugin to compile
Currently, according to this questions: Specify system property to Maven project
I tried the following setup (however this does not work as it is for a different plugin)
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>application.boot.AppStarter</mainClass>
<systemProperties>
<systemProperty>
<name>application.version</name>
<value>${application.version}</value>
</systemProperty>
<systemProperty>
<name>release.date</name>
<value>${timestamp}</value>
</systemProperty>
</systemProperties>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
How can i specify the properties in this plugin?
Java system properties which you add are only accessible by the process they are added to.So even if you manage to add some system properties during the Maven build, it will no longer be there when the build is done.
What will happen if you distribute your jar to someone else. How do you expect these properties to be available?
Solution
Refer this post to see how to access the artifactId and version at runtime
In a similar fashion you can add the timestamp entry as well to the src/main/resources/project.properties
buildTimestamp=${timestamp}
timestamp is not a pre-defined property like project.version or project.artifactId.So you will have to set extract the timestamp from the Maven property ${maven.build.timestamp} and set it as value to your timestamp property. This is already answered in this question.
Does anyone know how to read a x.properties file in Maven. I know there are ways to use resource filtering to read a properties file and set values from that, but I want a way in my pom.xml like:
<properties file="x.properties">
</properties>
There was some discussion about this:
Maven External Properties
Try the
Properties Maven Plugin
Using the suggested Maven properties plugin I was able to read in a buildNumber.properties file that I use to version my builds.
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0-alpha-1</version>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>read-project-properties</goal>
</goals>
<configuration>
<files>
<file>${basedir}/../project-parent/buildNumber.properties</file>
</files>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
This answer to a similar question describes how to extend the properties plugin so it can use a remote descriptor for the properties file. The descriptor is basically a jar artifact containing a properties file (the properties file is included under src/main/resources).
The descriptor is added as a dependency to the extended properties plugin so it is on the plugin's classpath. The plugin will search the classpath for the properties file, read the file''s contents into a Properties instance, and apply those properties to the project's configuration so they can be used elsewhere.