Maven - How to Install/Deploy timestamped SNAPSHOTS - java

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.

Related

Pushing local maven repos to server

I am setting up a maven repository for my workplace. The main reason for setting up a new private repository is that, our original nexus repo is hidden behind a VPN network. So anyone who wished to pull the dependencies. He needs to have a VPN connection in the working machine. Goal is to make the VPN secured artefacts under the newly created repo to make it available for CI pipeline.
Right now I am doing it as below, listing all the dependencies using following command:
mvn -Dmdep.copyPom=true dependency:copy-dependencies
Which send all the jars under target/dependency.
And then I using the following maven command:
mvn deploy:deploy-file
Which pushes all the dependencies in my newly created nexus, issue is that during setting deploy-file command I am passing a group id which is a generic one. And all the jars are pushed under that groupid. Which is different than my local name namespace/groupid, as different packages are under different group id and pushing all of them under a same group id makes them unusable as it messes with the namespace.
I am new to maven, and the approach I took feels like a hack. Can I use maven native functionality to solve the problem? What would be the standard way to solve the issue?
Nexus has a concept of proxy repositories , for the open source dependencies, you can create proxy repository to mirror the maven central repo and provide in the proxy information is maven settings and run a mvn install, during the resource generation phase of maven the nexus will automatically pull artifacts from the central repo and cache them in your proxy repository for future use.

What does it mean in Maven when it says the following artifacts could not be resolved although they are in Maven cache?

I get the following error:
The following artifacts could not be resolved: com.sun.jdmk:jmxtools:jar:1.2.1, com.sun.jmx:jmxri:jar:1.2.1: Failure to find com.sun.jdmk:jmxtools:jar:1.2.1 in https://artifactory.corp.adobe.com/artifactory/maven-identity-snapshot was cached in the local repository, resolution will not be reattempted until the update interval of artifactory-snapshot
However, both jars are in the Maven cache (.m2 folder) on my machine. I mean files named: jmxri-1.2.1.jar and jmxtools-1.2.1.jar. They are respectively in the folders com/sun/jmdk/jmxtools/1.2.1/ and com/sun/jmx/jmxri/1.2.1
EDIT: When I try the -o switch on Maven to force it to use the local jars, it says the artifact has not been downloaded before. Which is probably true since indeed the artifact is not in the repo but was copied from some other place to my Maven cache -- is it possible to force Maven to use the jars? The -o switch does not seem to force this and Maven seems to be able to detect that the artifact was not downloaded.
Try to delete corresponding artifact folders in maven local repo and rerun or just rerun using -U flag.
Which is probably true since indeed the artifact is not in the repo but was copied from some other place to my Maven cache
Manually copying jars is not the correct way to put artifacts into maven local repo. You should use mvn install:install-file instead. More details here: Guide to installing 3rd party JARs
The dependency on those jars is usually a consequence of a bug in the pom.xml for log4j 1.2.15.
Update to 1.2.16 or 1.2.17 and you will not need these jars any longer.
These particular artefacts date back to a time when Sun licensing did not permit the hosting of the actual jars in a public maven repository.
You were required to accept licence conditions, download them yourself and then manually install either into your local repo (using mvn install:install-file) or into your corporate repository manager (typically using a UI that it provides or mvn deploy:deploy-file).

maven - automatically build local dependencies

Currently my deploy workflow involves manually (i.e. in a script) cd-ing into each maven project directory and running mvn install. The problem is for local resources, i.e. other in-house code that I've written and am actively developing/maintaining, I don't know how to tell maven to build those resources itself when they are missing. Ideally each time I need to re-package the top level application it will rebuild any libraries it depends on that have at least one file modified.
If your (multi-module) project uses other in-house resources, what you actually need might not be to rebuild all those resources all the time, but to use a local maven repository. It can be a simple repository where resources are deployed using ssh or an HTTP transport (see the deploy plugin), or a real artifact manager such as Archiva, Artifactory or Nexus.
A repository manager does more than just hold your deployed artifacts, it can also clean the obsolete snapshots once the corresponding release has been made, and serve as a local cache for other repositories, including central.
Have a parent POM which contains all your modules. When you build the parent, all the modules that are part of parent POM file will be build as well.
You can inherit many things from the parent as long as you have the parent in your child.
Consider setting up Jenkins to automatically build your code. Jenkins has a useful feature that will rebuild projects that depend on newly built artifacts. Builds can be automatically triggered by simply committing your code.
If you're using several development machines (or working in a team) combine Jenkins with Nexus (Other options:Artifactory, Archiva) to provide a common store for shared artifacts. These tools are were designed to support Maven builds.

Speeding up jenkins builds

One of the most time consuming task Jenkins makes during every build is to download the artifacts into his local repository which it deletes.
While deleting my artifacts is fine. I don't understand the necessity in deleting 3rd party artifacts which were previously downloaded into it's local maven repository(.m2).
Is there any way to prevent Jenkins from deleting the local repository before build.
Thanks
You should install a Maven repository manager (MRM) like Sonatype Nexus, JFrog Artifactory or Apache Archiva and the downloads will be local to your network and very fast. Using a MRM is pretty much considered a necessity for any useful usage of Maven or any build tool with declarative dependency management since it allows you to cache artifacts as well as upload your own libraries and share them acros you developers as well as you CI builds.
If that is still not enough you can disable the private repository deletion per build or even use one shared repository per build, but that reduces the stability of the build since you are now mixing between builds and therefore introducing interdependencies.
While I agree with Manfred's recommendation to use a Maven repository manage I'd also recommend looking at how you manage the Maven local repository:
Prevent Jenkins from Installing Artifact to Local Maven Repository
When is it safe to delete the local Maven repository?
Ivy, Ant, Jenkins - Is it good idea to to a <ivy:cleancache> on Jenkins builds?
Maven does not normally purge the local repository, I'm guessing you have a periodic task that does this.

How do I prevent Maven 2 from searching remote repositories for specific local depedencies?

How do I prevent Maven 2 from searching remote repositories for specific dependencies that are in the local repository only?
How do I prevent Maven 2 from searching remote repositories for specific depedencies that are in the local repository only
Well, actually, Maven won't unless:
they are SNAPSHOT dependencies in which case this is the expected behavior.
they are missing a .pom file in which case you can provide it or generate it (see questions below).
Related questions
How do I stop Maven 2.x from trying to retrieve non-existent pom.xml files for dependencies every build?
Maven install-file won’t generate pom.xml
set up nexus as a repository manager.
add addtional remote proxied repositories if necessary
add your local hosted repository (hosted on the nexus server)
define a group of repositories in the correct search sequence with your local repo's first.
change your builds to point at the nexus group url (use mirrorOf=* in your settings.xml)
run your build and let nexus manage the local vs remote dependency resolution
Use fixed version numbers in your POM for your remote dependencies or the local versions you want to fetch from the local repository.
Maven tries to be friendly and fetch the latest and greatest of whatever which has no version number specified.
For a quick fix to not be waiting for the internet to be downloaded each time you build you can use mvn -o to force an offline build, and then it will not lose time trying to fetch new versions.
The answer of #crowne is also very good advice, especially setting up your own nexus and making sure all remote repos are configured there so you will never have unpleasant surprises when a repo dissappears some day.
To prevent Maven from checking remote repositories at all, you can use the -o flag. Otherwise, Maven will check that any snapshot dependencies are up-to-date. You can use a dependency manager such as Nexus to get fine-grained control over dependency resolution. The repository section in your pom.xml or settings.xml file also has an updatePolicy element that allows you to configure how often Maven will check for updated dependencies.

Categories