I'm using maven and my goal is to include the git commit hash in the version number. Something like : 1.1.{git_hash}.
I'm trying to follow this tutorial.
Q: is it possible to somehow override the version number specified in the version element of the pom file?
One way to achieve this is to use the git-commit-id-plugin. Add this to the list of plugins in the build section of your pom.xml:
<plugin>
<groupId>pl.project13.maven</groupId>
<artifactId>git-commit-id-plugin</artifactId>
<version>${git-commit-id-plugin.version}</version>
<executions>
<execution>
<id>get-the-git-infos</id>
<goals>
<goal>revision</goal>
</goals>
<phase>validate</phase>
</execution>
</executions>
<configuration>
<dotGitDirectory>${project.basedir}/.git</dotGitDirectory>
</configuration>
</plugin>
Note, that I've changed the phase to validate, so the revision number property is already available in when the artifact is packaged.
Then, add the following to the build section:
<build>
<finalName>${project.artifactId}-${project.version}-${git.commit.id.describe-short}</finalName>
<!-- your list of plugins -->
</build>
The git.commit.id.describe-short property is produced by the git-commit-id-plugin. It contains current git revision number (shortened to 7 digits) and an optional dirty indicator.
The produced artifact will look like this: examplelib-1.0.2-efae3b9.jar (or examplelib-1.0.2-efae3b9-dirty.jar in case there are uncommitted changes on your repository).
Additionally, you might also want to put this information to the MANIFEST.MF of your artifact. In such case add this to your list of plugins (the example assumes the artifact is a jar):
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestEntries>
<SCM-Revision>${git.commit.id.describe-short}</SCM-Revision>
</manifestEntries>
</archive>
</configuration>
</plugin>
Additional remarks:
I've shown a simple configuration of the git-commit-id-plugin. On their site you may find more options and properties. In addition to properties, that can be used inside pom.xml, the plugin can also generate a properties file containing information about revision.
As an alternative to git-commit-id-plugin, you might prefer buildnumber-maven-plugin. In order to get revision numbers this plugin requires a SCM plugin also configured in your pom.xml.
This setup may interfere with other plugins that transform or rename your artifacts (in my case it was the maven-shade-plugin - one of the sources jar it produces did not contain proper revision number).
The above accepted answer didn't work for me. I found the link https://dzone.com/articles/maven-git-commit-id-plugin, from where I copied the plugin code below. It worked first time for me. I now have the git.properties file automatically included in my target JAR file. Very useful for tracking.
<plugin>
<groupId>pl.project13.maven</groupId>
<artifactId>git-commit-id-plugin</artifactId>
<version>2.2.4</version>
<executions>
<execution>
<id>get-the-git-infos</id>
<goals>
<goal>revision</goal>
</goals>
</execution>
</executions>
<configuration>
<dotGitDirectory>${project.basedir}/.git</dotGitDirectory>
<prefix>git</prefix>
<verbose>false</verbose>
<generateGitPropertiesFile>true</generateGitPropertiesFile>
<generateGitPropertiesFilename>${project.build.outputDirectory}/git.properties</generateGitPropertiesFilename>
<format>json</format>
<gitDescribe>
<skip>false</skip>
<always>false</always>
<dirty>-dirty</dirty>
</gitDescribe>
</configuration>
Add finalName to build section to also have the version in the target file name
<build>
<finalName>${project.artifactId}-${project.version}-${git.commit.id.describe-short}</finalName>
...
</build>
Related
I am trying to use the maven-license-plugin to get license and header information for a multimodule project. I want to avoid having multiple copies of the license around and keep the pom files as easy to maintain as possible. To that end, I've put the plugin information into the parentPom in the element. I fully configured the plugin and put the necessary files into the parent project as well. So, in the parent, I have:
<pluginManagement>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>license-maven-plugin</artifactId>
<version>1.6</version>
<configuration>
<licenseName>my_license</licenseName>
<licenseResolver>${project.baseUri}/src/license</licenseResolver>
</configuration>
<executions>
<execution>
<id>first</id>
<goals>
<goal>update-file-header</goal>
</goals>
<phase>process-sources</phase>
</execution>
</executions>
</plugin>
</pluginManagement>
I then put a reference to this plugin into one of the children pom files:
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>license-maven-plugin</artifactId>
</plugin>
</plugins>
The child fails to build though because it tries to find the licenses.properties file along the child's project path, not the parent's. How do I get the children to look for licenses.properties in the parent project?
The solution to this was to use the classpath option as described here:
http://mojo.codehaus.org/license-maven-plugin/examples/example-add-license.html
Using a license resolver from classpath Since version 1.3, it is
possible to use a license resolver from classpath (means included into
a jar or any dependency of the plugin dependencies).
Just use the classpath:// protocol in the plugin configuration.
Imagine you have a license resolver in an artifact
com.my:extraLicenseResolvers:1.0 in package foo.bar
Next example show how to use this license resolver from classpath:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>license-maven-plugin</artifactId>
<version>1.6</version>
<configuration>
<licenseName>my_license</licenseName>
<licenseResolver>classpath://foo/bar</licenseResolver>
</configuration>
<executions>
<execution>
<goals>
<goal>update-file-header</goal>
</goals>
<phase>process-sources</phase>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.my</groupId>
<artifactId>extraLicenseResolvers</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</plugin>
What wasn't obvious about this is that you really do need to have a separate package with the license files. There doesn't seem to be a way to keep this information in the parent pom project.
In the end, this solution worked and we were able to have a single location for our license info that all of the children pom files use.
So I'm trying something I thought would be rather simple, I basically want maven to minify all my js and css files for me before building a war. My plugins look like this:
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<version>1.0.0</version>
<configuration>
<manifestLocation>META-INF</manifestLocation>
<instructions>
<Export-Package>!test.impl,test*</Export-Package>
<Import-Package>*</Import-Package>
<!--
add ,plugin.xml if it's present i.e.
src/main/resources,plugin.xml
-->
<Include-Resource>src/main/resources</Include-Resource>
</instructions>
</configuration>
</plugin>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>yuicompressor-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<goals>
<goal>compress</goal>
</goals>
</execution>
</executions>
<configuration>
<nosuffix>true</nosuffix>
</configuration>
</plugin>
The problem is that the YUI plugin does correctly minify the files, but just before the war is built it looks like it copies over all the files from my main source directory and thus wipes out the changes the YUI plugin had done.
I'm calling maven by the following: mvn compile war:war. I've been playing around for awhile with different settings, but so far I haven't found a way around this.
What I would like is for just after the war has copied over the files it needed from the src directory it would run the YUI plugin, but I tried all the permutations of phases on the YUI plugin, but that didn't seem to make any difference.
I've googled around, but pretty much everything I've read so far seems to indiciate that I should just need to drop the YUI plugin in there like I have and everything should magically work. So far I haven't seem to have found the magic.
The accepted answer doesn't work.
Much better is this answer (as pointed out by koga in his comment):
https://stackoverflow.com/a/11495021/11451
Here is what I ended up doing:
Step 1: minify the css and js
<plugin>
<groupId>com.samaxes.maven</groupId>
<artifactId>minify-maven-plugin</artifactId>
<version>1.7.2</version>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>minify</goal>
</goals>
</execution>
</executions>
<configuration>
<charset>UTF-8</charset>
<skipMerge>true</skipMerge>
<cssSourceDir>resources</cssSourceDir>
<jsSourceDir>resources</jsSourceDir>
<jsEngine>CLOSURE</jsEngine>
<nosuffix>true</nosuffix>
<webappTargetDir>${project.build.directory}/minify</webappTargetDir>
<cssSourceIncludes>
<cssSourceInclude>**/*.css</cssSourceInclude>
</cssSourceIncludes>
<cssSourceExcludes>
<cssSourceExclude>**/*.min.css</cssSourceExclude>
</cssSourceExcludes>
<jsSourceIncludes>
<jsSourceInclude>**/*.js</jsSourceInclude>
</jsSourceIncludes>
<jsSourceExcludes>
<jsSourceExclude>**/*.min.js</jsSourceExclude>
</jsSourceExcludes>
</configuration>
</plugin>
Step 2: overwrite css and js in the war with minified files
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<webResources>
<resource>
<directory>${project.build.directory}/minify</directory>
</resource>
</webResources>
</configuration>
</plugin>
Use the war generator and add the configuration to exclude the sources file.
Example:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>${war-plugin.version}</version>
<configuration>
<warSourceExcludes>js/**/*.js</warSourceExcludes>
</configuration>
</plugin>
After that you need to include your target files to your war. You do this by setting the "prepare-package" phase of maven lifecycle (I'm using Minify plugin) and adding the files on Minify configuration (jsSourceIncludes,cssSourceIncludes,...)
For example:
<plugin>
<groupId>com.samaxes.maven</groupId>
<artifactId>minify-maven-plugin</artifactId>
<version>1.7.2</version>
<executions>
<execution>
<id>default-minify</id>
<goals>
<goal>minify</goal>
</goals>
<phase>prepare-package</phase>
<configuration>
<jsSourceDir>/js</jsSourceDir>
<jsSourceIncludes>
<jsSourceInclude>/**/*.js</jsSourceInclude>
</jsSourceIncludes>
</configuration>
</execution>
</executions>
</plugin>
What happens is that the config above is running the compressor on the process-resources phase, but then the package phase overwrites these files with the original ones.
By changing the phase to package, it should work:
<execution>
<phase>package</phase>
<goals>
<goal>compress</goal>
</goals>
Now the compression is done after the files where copied to target in order to build the WAR content.
The reason why this is happening is that only compressing files without concatenating them or renaming them with a suffix is not the most common use case for the plugin.
Normally we want to compress and concatenate files into only one file, and give it a new name.
The new name is usually something like originalname-min.css / original.name-min.js where .min is the suffix, so removing the nosuffix option on the config above would also work.
Edit: Log example
[INFO] --- yuicompressor-maven-plugin:1.1:compress (default) # yui-compressor-test -
[INFO] prettify.css (817b) -> prettify.css (617b)[75%]
[INFO] total input (1510b) -> output (1134b)[75%]
as stated above maven-war-plugin overwrites files created by minify plugin.
it seems that this cannot be changed. however wanted behavior may be achieved by simply changing project structure.
here example what I did with my project. I'm using minify-maven-plugin and spring framework, static files are stored in static directory.
1) move static directory from src/main/webapp to src/main/resources
2) change minify plugin config in pom.xml. so source points to resources and target points to classes:
<webappSourceDir>src/main/resources</webappSourceDir>
<webappTargetDir>target/classes</webappTargetDir>
<jsSourceDir>static</jsSourceDir>
<cssSourceDir>static</cssSourceDir>
3) change spring config. so spring is serving static files from class path:
<mvc:resources location="classpath:/static/" mapping="/static/**"/>
and now
mvn clean && mvn package
produces correct war with minified files inside /WEB-INF/classes/static
You should take a look to Minify Maven Plugin which sounds like the thing you need.
Let me know if you need any help configuring it.
I can deploy a jar by using the following in my pom.xml and running mvn deploy:
<distributionManagement>
<repository>
<id>releases</id>
<url>http://${host}:8081/nexus/content/repositories/releases</url>
</repository>
<snapshotRepository>
<id>snapshots</id>
<name>Internal Snapshots</name>
<url>http://${host}:8081/nexus/content/repositories/snapshots</url>
</snapshotRepository>
</distributionManagement>
And I can build an executable jar-with-dependencies using the following:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>create-executable-jar</id>
<phase>deploy</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>my.company.app.Main</mainClass>
</manifest>
</archive>
</configuration>
</execution>
</executions>
</plugin>
Problem is I don't know how to stitch these together to deploy the executable jar to my Maven repo. I don't really know if this is accomplished by a new plugin or by adding a goal or other step to the existing assembly plugin.
If you bind the assembly to the packaging phase, it will install in your repository both the "regular" jar and the with-dependencies jar when you do a build:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>my.company.app.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
Then simply run mvn clean install deploy to upload both jars to your repository.
In order to build a (so-called) Über JAR and deploy it using maven, you could also use the shade plugin. The following code is taken from their website but I've made one or two projects using this feature.
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>jackofall</shadedClassifierName> <!-- Any name that makes sense -->
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
In this configuration you get the Über JAR as one deployment besides the normal JAR. The user of your JAR can then decide to pull the all-in-one package or the JAR with dependencies based on the classifier.
I'll usually use the shade plugin to build Über JARs (or modify the JAR in a way) and use the assembly plugin to build things like installation packages (containing the JAR and possibly other things). I am unsure what the intended goals of the single plugins are however.
The following worked. I'm going to leave this question open a bit because I'm not positive this is best practice, but working is something.
Problems I notice are that I made up the ID name and I don't know if this is usual practice and that I have to hard code the jar name; it isn't inferred from anything else.
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.7</version>
<executions>
<execution>
<id>deploy-executable</id>
<goals>
<goal>deploy-file</goal>
</goals>
<configuration>
<file>target/Monitoring-Client-1.0-SNAPSHOT-jar-with-dependencies.jar</file>
</configuration>
</execution>
</executions>
</plugin>
Essentially my difficulty doing this revealed the fact that my pom.xml was way off the rails already. Everything would have snapped into place on its own. I was formerly doing:
Save all the dependencies into a lib folder
Build a jar with a classpath slurping up that lib folder
Use the assembly plugin to make another deployable jar
I think there were several reasons this sort of made sense along the way, especially when my libraries were not well-factored from my applications.
However by deleting 1 and 2 all that is needed is the distributionManagement section and the deploy phase works automagically. So all in all this is an amazing case of literally adding functionality by deleting large swathes of code.
First you shouldn't do the creation of the ueber jar in the deploy phase it's better to do this in the package phase. Furthermore the created jar file is usually automatically attached to your artifact and will be transfered to the remote repository (in your case Nexus). You can check this if you simply try to do a mvn install and take a look at the output if the created jar is installed into the local repository.
To deploy the results into nexus you need to call mvn deploy.
i am creating a standalone java application with maven, and i am including the dependencies in the jar file with maven-dependecy-plugin as follows:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/classes/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>theMainClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>create-my-bundle</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
this includes the dependencies in the generated jar file in a lib folder, and the jar runs and works fine, but the issue is in the other generated jar file appname-1.0-jar-with-dependencies.jar.
ISSUE: i am not sure if it's an issue or not, but i noticed in target folder in the generated appname-1.0-jar-with-dependencies.jar, that it contains duplicate application files like:
all sql,property files,xml files exists twice.
all java classes .class file exists twice.
there are lots of overview.html and license.txt files related to the dependencies.
i am not sure if that's feels right or not, also i need someone to clarify for me what is the importance of this generated jar file, since i am not familiar with this plugin.
please advise, thanks.
Since you have mentioned jar-with-dependencies, I assume you are using maven assembly plugin to assemble your project artifacts along with the dependant jars into a single jar.
I suspect that your project artifacts are getting into the jar-with-dependencies twice - due to a property useProjectArtifact of dependencySet which is true, by default. You can set this property to true in your assembly descriptor and see if it addresses your issue.
In the specific case above, maven dependency plugin does not seem to be doing anything useful. maven assembly plugin automatically packages all its dependencies into a single distribution as per configuration.
But do note classpath issues if you create an executable jar-with-dependencies. You may want to create a zip or tar.gz instead.
The configuration used above is the default and does not allow for customization. You may want to use an assembly descriptor file, where you can set the property mentioned earlier or other options.
I am using a different plugin (ant4eclipse) to jar my files. What is the best way to avoid the maven-jar plugin from executing?
I tried to remove the <plugin>maven-jar-plugin</plugin>
I tried to <exclude> ** / * < / exclude>
I tried to <skip>true</skip>
None worked
In Maven 3.0.x (I tried 3.0.2) you can disable maven-jar-plugin by binding the default-jar execution to a nonexistent phase, as #bmargulies suggested. Unfortunately that doesn't work in 2.2.1, but you can prevent it from interfering with your own jar by setting an alternative <finalName> and <classifier> for the default-jar execution; it will still create a jar, but it will be set as a secondary artifact for the project and won't overwrite the one you've created. Here's an example that should work in both Maven 2 and Maven 3:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>test</artifactId>
<version>0.1-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>default-jar</id>
<phase>none</phase>
<configuration>
<finalName>unwanted</finalName>
<classifier>unwanted</classifier>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Once you've disabled maven-jar-plugin, maven-install-plugin may give you trouble too. In Maven 3 it can be disabled the same as maven-jar-plugin: bind default-install to a nonexistent phase. However, in Maven 2 maven-install-plugin requires that the target/classes directory exist, and it will install the dummy jar when there isn't a primary artifact present.
This should do the trick - notice the use of <id>default-jar</id> and <phase/>.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>default-jar</id>
<phase/>
</execution>
</executions>
</plugin>
</plugins>
</build>
In my case, I only wanted to disable the jar plugin because the jar was empty. You can use the skipIfEmpty option in the plugin configuration
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<skipIfEmpty>true</skipIfEmpty>
</configuration>
</plugin>
What happens if you declare this?
<packaging>pom</packaging>
Even if it does what you're looking for, be careful. I'm not sure if there could be negative side effects -- such as other maven projects that depend on your jar not being able to locate it.
Using maven 3.3.9, the following worked for me:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.2</version>
<executions>
<execution>
<id>default-jar</id>
<phase>none</phase>
<configuration>
<finalName>unwanted</finalName>
<classifier>unwanted</classifier>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>3.0.0-M1</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
So in case of the maven-jar-plugin, I bound it to a non-existent phase. For the maven-install-plugin, I used the "skip" configuration parameter. The documentation about it says: "Set this to true to bypass artifact installation. Use this for artifacts that does not need to be installed in the local repository."
Explicitly bind the jar plugin to a phase that doesn't exist.
As other's have said, it's not possible to turn it off, other than using <packaging>pom</packaging>, which turns everything off and is probably not what you want.
Even though it will generate twice, a working solution is to bind your jar process to the package phase, as that is guaranteed to run after the default. By overwriting the same JAR file, you'll find that yours is used wherever the original would have been.
I am using a different plugin to jar my files. What is the best way to avoid the maven-jar plugin from executing?
First, the jar:jar goal is bound by default on the package phase for a project with a packaging of type jar. Second, there is no way to unbind a plugin bound to a phase. So, if you are using another plugin(?), either accept to produce 2 JARs or change the packaging (but I don't think this will work well).
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>