Maven WAR packaging libraries with timestamp - java

I have several libraries which I've manually deployed to my Nexus repository using:
mvn deploy:deploy-file -Durl=[url] -DrepositoryId=[repoId] -Dfile=[filePath] -DgroupId=[gId] -DartifactId=[aid] -Dversion=[v] -Dpackaging=jar
I did this because they are legacy jars and quite a large amount of them for which I've automated the process.
The problem I'm having is in packaging a WAR. The dependencies come down just fine, but when the war is generated they have the version+timestamp appended to the end. I have several other projects where this doesn't appear to be the scenario - i.e., after multiple packagings and deployments to a given server the lib directory [for the project] contains:
[jar].[<version>-timestamp1].jar
[jar].[<version>-timestamp2].jar
[jar].[<version>-timestamp3].jar
[jar].[<version>-SNAPSHOT].jar <== this entry alone would be ideal
Also, I'm not using any specific plugins just invoking:
clean package
Is it possible to eliminate the timestamp when packaging the war?

You may need to ask yourself why you need to eliminate the timestamp.
If you just want to download the latest SNAPSHOT version, Nexus provides REST API to download latest SNAPSHOT artifact just directly using your snapshot version as version parameter, such as 1.0-SNAPSHOT. e.g.
http://<your-nexus>/service/local/artifact/maven/redirect?r=<your-repo>&g=<the-group>&a=<the-id>&v=1.0-SNAPSHOT
From the API doc, the version parameter can support LATEST, RELEASE and SNAPSHOT versions.
Version of the artifact (Required) Supports resolving of "LATEST", "RELEASE" and snapshot versions ("1.0-SNAPSHOT") too.
Furthermore, with timestamp each SNAPSHOT build has it's unique version, which gives you the chance to download a specified SNAPSHOT build such as v=1.0-20140822.145007-2.
If you want to limit the number of snapshots, you can take a look this one: How to limit number of deployed snapshots artifacts in Nexus?

Related

Ensure Maven pulls latest version of release

This question is a little different than the other "checking for latest dependency version" type questions.
Let's say we have a project, DepProjA, that builds and publishes an artifact for our other Java apps to import as a dependency. For example, AppProj1 lists DepProjA as a dependency in its pom.xml file.
<dependency>
<groupId>com.mycompany.depproj</groupId>
<artifactId>depproja-lib</artifactId>
<version>feature-addthisfeature</version>
</dependency>
As you may notice, DepProjA, publishes "feature" versions of this JAR with the version named after the working branch name. This is so that other teams can test these particular feature updates before they are published as an official version update. If a bug is found and the fix is pushed under the same branch, the "feature" artifact is updated. However,when we rebuild AppProj1 to try and pull and utilize that latest artifact, it seems to be using the previous local version instead.
Is there an option, either in the pom.xml, or the mvn CLI options, so that maven will always pull down the latest artifact instead of using whatever version is cached? I know I can do a "blanket approach" like purging cache and such, but looking for something that targets specific dependencies. Kind of similar with Docker images where the tag itself won't change, but the underlying SHA can be updated when a new version of that tag is published.
An alternate idea I don't even know is possible: When publishing an artifact, is there a way to add custom metadata or labels that I could then reference? For example, I add a "cicdlabel" that could reference the pipeline ID that published the latest version. Then, I could change that in the application's dependency info when I know there is a change:
<dependency>
<groupId>com.mycompany.myproject</groupId>
<artifactId>myproject-lib</artifactId>
<version>feature-addthisfeature</version>
<cicdlabel>12345</cicdlabel>
</dependency>
In Maven by design released artifacts are immutable.
You can not update the same release version of artifact in Maven central.
It ensure that your build is reproducible, when we change content of released artifact the same build can break in the future.
In your case you should use SNAPSHOT versions for your artifact, and SNAPSHOT version can be updated.
You can use updatePolicy for your repository configuration in your settings.xml.
Yo can use mvn -U .. for update SNAPSHOT versions on every build.

How to automate reliable builds when Maven dependencies are only available for a limited time?

I have a Maven project which has several dependencies that:
Are hosted on a third-party artifact repository, which only holds the x most recent artifacts.
Are snapshot versions. (There are no releases available.)
Once I build my project, I need other members of my team to still build that same version of the project several years from now. However:
The dependency snapshot version I used may no longer be available on the third-party repository.
Even if it's available, the dependency may have been updated without changing the snapshot version number.
Is there a way to automatically create a shared repository of the dependency artifacts Maven retrieved when building the project for the first time? This would cause each dependency artifact to only be retrieved once from the third-party repository.
Set up a Nexus or Artifactory server in your company.
Add all the external repositories as remote repositories to that Nexus/Artifactory and run all builds through Nexus/Artifactory.
The Nexus/Artifactory will cache all the artifacts you have used, so no risk that some artifact is not available in the future.
For Snapshot version: If you really need to use Snapshot versions, use versions:lock-snapshots (https://www.mojohaus.org/versions-maven-plugin/lock-snapshots-mojo.html) before, so that you have reproducible version numbers.

Maven Deploy Plugin Replace the Existing SnapShot Jar in Artifactory

I am using the Maven deploy plugin(3.0.0-M1/2.82)
to upload Snapshot jar to Jfrog Artifactory, but Plugin builds the SnapShot jar with the timeStamp and build Number(Default Behavior Of Maven Build with Timestamp while Remote Repository ) and says it uploading with name
example: project-extension-0.0.2-20200506.171928-1.jar but it uploads with SnapShot
name: project-extension-0.0.2-SNAPSHOT.jar(0.0.2-SNAPSHOT its Parent POM Version ) and replace it with the previous build Jar.
This is how SNAPSHOTs work.
The file is uploaded with a timestamp name (and also saved as such internally). But usually just specify the version as 0.0.2-SNAPSHOT and Maven resolves the latest timestamp for you.
Artifactory keeps the different versions, but can be configured to keep only the last n SNAPSHOTs.

Uploading sources to nexus makes snapshot dependencies unavailable to maven

When we do mvn install deploy to a repository ${repository-jars} these dependencies can be used by others as intended.
When we afterwards upload sources to another repository ${repository-sources} the dependencies are no longer resolved correctly.
mvn deploy:deploy-file
-DgroupId=foo
-DartifactId=bar
-Dversion=1.0-SNAPSHOT
-Dfile=target/bar-sources.jar
-Dpackaging=jar
-Durl=${url}
-Dclassifier=sources
-DrepositoryId=${repository-sources}
Everything looks correct in nexus and both repositories are available in a regular Repository Group.
The hypothesis is that maven tries to use the latest uploaded artifact and ends up downloading the sources jar instead somehow ignoring the classes modifier. This is verified by first uploading sources and then do a maven deploy where it works as intended.
What is the correct way that allows us to upload sources in a separate job that runs after a deploy?
In examination, Maven is creating two different snapshots, and when you attempt to get latest, it's getting the newest one (which is sources) from the Group you've setup.
What you might actually try is putting them in the same repo, and separate them using Content Selectors. This is our newer version of Repo Targets from Nexus Repository 2.

Maven - How to Install/Deploy timestamped SNAPSHOTS

Env : Maven 3.3.9
Hi,
I have a maven jar module with version as 1.0-SNAPSHOT. When i do mvn install, the jar installed into local repository (~/.m2/repository) does not have timestamp. I agree that its not a common scenario where you would like to have timestamped jars in your ~/.m2/repository repo. But still couple of questions:
Does mvn install append timestamp automatically? Looking for some
configuration way rather than use ${timestamp} in final name.
Does automatic timestamp mechanism applies to mvn deploy?
Is there a way to tell maven to use ~/.m2/repository
itself for mvn deploy?
Thanks,
Rakesh
The mvn install will only put your project into your local cache which means it makes it available for other projects on your machine.
mvn deploy will deploy the artifacts into your remote repository which is usually a corporate repository manager.
In case of a SNAPSHOT this means this artifact has not been finalized and is under developer. This means you can create several states of the same version like 1.0.0-SNAPSHOT. The time stamp which is created during the deployment to a repository manager is intended to have different artifacts available for development. You can control via -U option if you like to use the most recent version of the SNAPSHOT's.
After you feel ready you make a so called release which will set the version to something like 1.0.0 (without SNAPSHOT) which is deployed as well but into a release repository which is immutable.
Furthermore having timestamps in your local cache $HOME/.m2/repository does not make really sense, cause you can control when you install an artifact there and no one else and you should prevent using finalName change cause this is only intended for your target folder and not for your local cache.
And finally using the local cache for mvn deploy does not make sense, cause what is the idea behind that? Best is to start using a repository manager like Nexus, Artifactory or Archiva in particular if your are working in a corporate environment.
In addition to #khmarbaise's answer see the following references:
Maven / Introduction to Repositories:
There are strictly only two types of repositories: local and remote. The local repository refers to a copy on your own installation that is a cache of the remote downloads, and also contains the temporary build artifacts that you have not yet released.
Remote repositories refer to any other type of repository, [...]
Maven: The Complete Reference, 15.2.8. Repositories:
Repositories are remote collections of projects from which Maven uses to populate the local repository of the build system.
Repository - SNAPSHOT Handling reads:
This documentation was targetted at Maven 2.0 alpha 1. It is here only for historical reference and to be updated and integrated into the Maven documentation.
But I didn't find any latest documentation where this has been integrated. (#khmarbaise?)
Timestamped files are not created on install in the local repository for reasons of disk space preservation. However, when a SNAPSHOT is resolved and downloaded, it is saved with its timestamp version number (eg: 0.15-20050401.150432-2).
Understanding Maven Version Numbers
Maven Dependency Resolution - A Repository Perspective
Long story short:
The same snapshot version can be deployed to a remote repository from different hosts, so they have to be distinguished there somehow. And they are distinguished by timestamps (and a build number).
There will be an artifact with a timestamp (and build number) in the local repository only if Maven resolved and, hence, downloaded it from remote.
So:
No.
Yes.
Would break Maven's repositories handling of local vs. remote.

Categories