Maven uses different timestamps when building snapshot artifacts in a large project - maven

We have a large maven 3 project with around 250 modules. All modules have version 1.0-SNAPSHOT and modules tree has single parent module with the same version as a tree root.
Project is built with Bamboo nightly and artifacts are installed to a Nexus repository using command "mvn clean install".
It happens that part of modules are built with one timestamp while the rest with the other, something like:
module1-1.0-20121127.150154-7.jar
module100-1.0-20121127.150527-7.jar
In another project I was trying to set dependency to artifacts of this project using specific version of a snapshot dependency (as discussed in this question Maven specific version of a snapshot dependency) but failed to build due to the problem described above.
Does anyone know why maven would use different timestamps and how to fix that?

MNG-6754 was finally fixed in 3.8.2.

Related

Maven does not take newly built snapshot, uses global repository

I am trying to build a patch branch, into which I build both a parent(a snapshot) and a child(a snapshot as well) as modules listed in an aggregation pom.
Maven finds out everyone depends on the parent, and builds it first, BUT it does not use the newly built parent when I build into clean repository.
When built immediately afterwards, against the same repository, that the built Parent 2.2.5- Snapshot is installed in already, everything works correctly and the patched parent is used in its children.
The problem is that the CI build is always built on a clean repo, and hence, the parent that we use is the one from the global repository, not the local one.
Is this wrong pom.xml, maven settings or possible a bug in maven algorithm?
I tried
mvn clean install -nsu
but in vain.
If you use the option -nsu which means:
-nsu,--no-snapshot-updates Suppress SNAPSHOT updates
It will never use the most up-to-date snapshots. To force maven to do so you should use:
mvn -U clean install
instead.
It turned out the major problem was that we were building the parent pom together with the rest.
Maven downloads all parents first and then resolves dependencies.
So, it was not correct that the parent is listed together with the rest, as a module, when this is a clean build and this version of the parent was not yet deployed(children saw an old snapshot of it instead).
Solution 1: use relativePath to point to the branched parent. This is the better solution in case you do not have very complex hierarchy of modules.
Solution 2: build and deploy the parent of the patch first, so that it is seen by all children, and hence they use correct versions of each other.

Maven3 and Jenkins: Deploying multiple classifer

we are currently migrating from maven2 to maven3.
Now we have a problem with the new "SNAPSHOT" policy of maven3 in one of our shared projects.
The project provides different configuration using filters to set different setting for different environments (dev, int, production) which are devided throw classifier.
In our Jenkins buildserver produces and deploy this three classifier in our local company repo: The dev in the main maven goal, the others as post steps.
In maven2 this was no problem, because after the deployment we had in our repository:
artifact-1.2.0-SNAPSHOT-dev.jar
artifact-1.2.0-SNAPSHOT-int.jar
artifact-1.2.0-SNAPSHOT-prod.jar
With maven3 we have now this timestamped versions:
artifact-1.2.0-20140212.103043-1-dev.jar
artifact-1.2.0-20140217.174231-2-int.jar
artifact-1.2.0-20140311.125512-3-prod.jar
Now the build of the other projects with the classifier dev or int breaks, because the lastest SNAPSHOT version is the 3rd one (prod) and the dev and int cannot be resolved from our repository.
As far as I know it's not possible to tell maven3 to deploy the "good old" SNAPSHOT without a timestamp. Is there a solution to process all configuration inside one maven3 call? Or how can we configure Jenkins to do that all as "one SNAPSHOT"?
Thanks in advance
Update 1
As followed the Post steps are configured:
Maven Goals:
Maven Version: 3.1.1
Goals: clean deploy -Pint
Maven Goals:
Maven Version: 3.1.1
Goals: clean deploy -Pprod
This won't work as you have planned. As you said, there is no way to use non timestamped repositories in Maven 3.
You have two options:
Either adapt your build in a way that creates all classifiers in one build (possibly by using different modules instead of different classifiers)
Or create a your own deploy mechanism.
I would strongly recommend solution 1.
From my understanding the artifacts generated from Maven 3 are coming with timestamp in their name like artifact-1.2.0-20140212.103043-1-dev.jar which are causing the failure of dependent builds.
As you need Maven 3 to generated artifacts with naming convention artifact-1.2.0-SNAPSHOT-dev.jar , this can be achieved by using "finalName" tag in the corresponding POM.xml which are generating these artifacts .
Controlling maven final name of jar artifact
Regards
Jyotsna

Maven: how can I skip building artifacts which exist in central repo?

My situation: I have project which contains several Maven modules. I make changes to one of them. Suddenly I find out, that my project is no longer possible to be built because of the errors in other modules. To fix this I need to run SVN UPDATE and rebuilt the project.
My assumption: probably, during the build process of my module some of the artifacts are taken from central repository and have the most newest version, while others are still outdated and taken from my local repo.
A question: I don't want to rebuild my project each time someone updates ANOTHER Maven module. I want to download the already built artefacts from the central repository without rebuilding them by myself. Is it possible?
You can tell Reactor which modules to build. In your case when you only change a single module and want to speed up the build you can pass -pl (Project Location) parameter to maven. For example:
mvn -pl module-with-changes
That will build single module, while taking other dependencies from your local Maven Repository or download from Central (whatever is the latest). That said, if you already ran mvn install for whole project and other artifacts have not been updated in Central repository, then Maven will see your local artifacts as latest and will not re-download them.
Another issue you might get with -pl parameter is when other modules in your project depend on the module that you are building. If there is a problem in dependent module you will not see it by building only the dependency model. To avoid that you can pass -amd (Also Make Dependents). Like this:
mvn -pl module-with-changes -amd
That will trigger the build for module-with-changes + modules that depend on module-with-changes + their dependents.
You can get more info about Reactor parameters from here:
http://www.sonatype.com/people/2009/10/maven-tips-and-tricks-advanced-reactor-options/

Maven build : How to resolve the workspace artifacts without installing them to repo and without using m2eclipse

I've worked a little with m2eclipse in Eclipse Indigo and now I'm trying to use Maven from command line without Eclipse and without m2eclipse plugin. The m2eclipse has abililty to resolve the artifacts from the workspace without installing them to repository and this feature allows me to run my build without problems in Eclipse , but in CMD I'm getting the errors of missing jars.
[WARNING] The POM for AAA_7.1.1:ConfigurationView:jar:0.0.1-SNAPSHOT is missing, no dependency information available
[WARNING] The POM for AAA_7.1.1:Beans:jar:0.0.1-SNAPSHOT is missing, no dependency information available
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[ERROR] Failed to execute goal on project Client: Could not resolve dependencies for project AAA_7.1.1:Client:pom:0.0.1-SNAPSHOT:.......
Our goal is to keep the repo clean as much as possible , that's the reason why I'd like to keep it working in a such way.
So my question is how to resolve the dependencies without installing them to repo and if it's possible at all?
IMO, the standard way to go with Maven is mvn clean install.
But if I understand well your problem, you want to keep your local repository as clean as possible ?
One way to do that would be to use multiple local repositories, but I don't think it's possible at the moment (Maven 3.0).
However you can use alternate local repo with -Dmaven.repo.local or alternate settings with mvn --settings (see answer).
See also :
Previous question : maven workspace local repository
JIRA : Allow multiple local repositories (Unresolved)
Local repository separation -> workspaces don't seem to be implemented at the moment...
Basically you want a maven build, where the reactor contains all your 97 modules. To do this:
Create a parent, which contains all those 97 modules as children (if you are already multi module, you just need to configure the already existing parents to be the children of this new parent). Than start your build at that new parent. The convention is normally to have the parent in the upper directory. But you may also use relative paths that contain .. for the module location specification. There is also no need to inherit from the new parent in the existing parents. So you do not need to change any of the existing poms.

Tycho resolves the wrong version of my own manifest-first artifacts

Consider the following scenario: My application has some dependencies on my own POM-first artifacts (built with pure Maven) and some dependencies on my own manifest-first artifacts (built with Tycho). For the POM-first artifacts, Tycho resolves the exact the version I specified in the POM. For the manifest-first artifacts, Tycho resolves the locally built units which may have a higher version.
In my concrete case, I specified a dependency in the pom.xml to the manifest-first artifact in version 1.2.0, but I get warning "The following locally built units have been used to resolve project dependencies" with version 1.3.0.2012xxx.
I have already found following bugs and discussions, but I don't understand why there is a difference in Tycho resolving POM-first and manifest-first dependencies.
https://bugs.eclipse.org/bugs/show_bug.cgi?id=355367
http://dev.eclipse.org/mhonarc/lists/tycho-user/msg01673.html
Dependency-resolution is a two-step process in Tycho:
First, Tycho computes the so-called target platform, which is
the set of artifacts that are considered for dependency resolution.
In this step, Tycho evaluates the POM dependencies according to the
Maven rules and adds the result to the target platform. Also, all
Tycho artifacts you have built locally with mvn install are added
to the target platform.
Then, Tycho resolves your project's dependencies (from the
MANIFEST.MF, feature.xml, etc.) according to the OSGi rules. Unlike
in Maven dependencies, OSGi dependencies are typically specified as
version ranges. So if you write
Require-Bundle: my.bundle;bundle-version="1.2.0"
you are saying that you want version 1.2.0 or later. You typically don't want to specify an exact version here, because this would have implications on the runtime. But you do want to control what happens at build time, which is why there are various ways to control the content of the target platform.
In your particular case, you have your POM-first artifacts in the target platform in the version specified in the POM. Then, you also seem to be specifying a POM dependency to your Tycho artifacts (which is uncommon, but okay), so you will have the Tycho artifacts in the specified version in the target platform. But since you have also built a newer version of the Tycho artifacts locally with mvn install, these will also be in the target platform. The dependency resolution (step 2) hence has a choice between two versions, an will typically pick the later version.
To prevent the locally built artifacts from being added to the target platform, you can delete the file ~/.m2/repository/.meta/p2-local-metadata.properties. (I'm assuming you already know this, but just to be sure. Bug 355367 will also bring a alternative, more convenient option in 0.16.0.)
And now I finally get to your question why the behaviour is different for POM-first artifacts compared to Tycho artifacts:
Assume multiple Tycho artifacts are built together in the same reactor. Then each artifact can use the other artifacts as dependencies without needing any specific target platform configuration, e.g. you don't need POM dependencies to the artifacts in the same reactor. (Or in other words: upstream artifacts from the same reactor are automatically part of a module's target platform.) So in order to support re-builds of parts of a Tycho reactor (after a mvn install of the full reactor), locally installed Tycho artifacts need to be added to every module's target platform. Tycho can't know if they were originally part of the same reactor, so it just adds them all.
For POM-first artifacts, the reference to the artifact is always there (through the Maven configuration inheritance), even if only a part of a Tycho reactor is built. Therefore there doesn't need to be any mechanism for picking up any version of the locally built POM-first artifacts, but Tycho can add the exactly specified version to the target platform.
For those interested to force tycho to ignore local artifacts when resolving the target platform, add the CLI tycho.localArtifacts=ignore as in e.g.
mvn clean install -Dtycho.localArtifacts=ignore
More details can be found on the Tycho-Target Eclipse Wiki

Resources