I have an application that uses maven 2.2.1 for building. I want to use a plugin that needs maven3 to run during deploy phase of build. Is this possible. Just want to know if someone solved this scenario in a unique way.
You'll either need to use different Maven installations for different phases or convert everything to Maven3.
Having just converted my build process to Maven3, there is one huge gotcha in Maven3: version ranges on snapshots are totally mucked up. There was an attempt to rectify version weirdness in Maven2 and instead broke Maven3. Version ranges with release artifacts work fine, just not snapshot, so something to beware of.
Related
We are using Maven as build manager and Nexus as our artifact repository.
From time to time we are having this dependency problem and Maven is not able to find the artifact in Nexus by a slight difference in the snapshot version number. In this case, the difference seems to be 1 second.
Currently, a build is failing, maven is looking for
SOME_ARTIFACT-0.0.1-20181217.115318-337.jar
but on the Nexus we have
SOME_ARTIFACT-0.0.1-20181217.115317-337.jar
This is not happening all the time, but from time to time I see this problem, and in order to solve this I need to redeploy SOME_ARTIFACT before building the application that depends on SOME_ARTIFACT.
Do you have any idea why this is happening? I know I can use release versions and totally avoid this snapshot issue but this SOME_ARTIFACT is under constant update and development, so I don't wanna keep releasing, plus, what I want is to figure out the reason behind this problem not to basically avoid it.
Maven version: 3.5.0
NEXUS version: OSS 3.12.1-01
Any help is appreciated.
Thanks!
Thanks for providing the Maven version. Likely you are being impacted by https://issues.apache.org/jira/browse/MNG-6240. Update Maven (or downgrade to 3.3.9) and that should help.
In development, I can reference the latest version of an artifact as 1.2.3-SNAPSHOT. Now I need the same behaviour for release candidates, i.e. I would like to be able to depend on the latest release candidate (there should also be a procedure for the developer to declare development versions as release candidates).
I am not sure how to implement this behaviour properly. Should I use an additional repository for release candidates and move development versions to this repository if the developer requests it? Or can I somehow define a "second snapshot list", like 1.2.3-RC?
You can get there be re-configure a few things:
use a version range for the dependency
change the updatePolicy for the repository you store the release candidates. see https://maven.apache.org/settings.html (updatePolicy). If you store the artifacts in a maven proxy usually you need to allow to overwrite releases.
Remember in a multi module build that they might upload modules before detecting a failed build (due to mvn deploy being a phase not a goal). You need to verify the complete build is ok before starting to upload artifacts in the maven repository. Or stage them somehow.
Remember this will most certainly prevent your builds being reproducible. Since an RC dependency might change between builds. You would need to change the version range - which is not always an issue. Ranges may work for you.
I've better experience to let developers stay on snapshots but have the CI server set an explicit version (for example using the versions plugin) prior to deployment / releasing for the dependency the artifact uses.
My setup:
I'm using Grails 2.3.8
I have several private plugins I publish to my local Nexus repository manually via "grails publish-plugin"
I have several Grails applications that use these plugins
Distributed development team
My goal:
Able to deploy new versions of my private plugins and have my Grails apps automatically use those latest versions without having to modify their BuildConfig.groovy files
I know about inline/inplace plugin definitions and that is not what I want
Possible solutions:
As I understand it there might be at least two ways of achieving my goal:
Deploy snapshot versions of my plugins and have my Grails apps use those snapshot versions (e.g., version = "0.1-SNAPSHOT")
Configure my Grails apps's BuildConfig.groovy to use "latest.release" or Maven version ranges. Examples:
compile 'com.mycompany:some-plugin:latest.version'
compile 'com.mycompany:some-plugin:[0.1,)'
The problem:
The two methods above sort of work.
They both result in the latest version of my plugin to be downloaded, at least initially. However, if I publish a new version of the plugin (be it snapshot or release), re-running "grails run-app" on my Grails applications do not attempt to download/install the newer versions which are available.
I feel like the maven-metadata-*.xml files in my M2_HOME local repo are limiting the versions which are known to exist (even though Nexus has newer versions available).
When I define my Nexus repo using mavenRepo(), do I need to pass in some parameters to tell Grails to always check for new versions on the remote repo and not rely on the local repo?
Graeme's suggestion here does not seem to help either: Dependencies and lastest.release
Any help would be great. :-)
Have you configured the updatePolicy for the repository? See
http://grails.org/doc/latest/guide/conf.html#changingDependencies
Section "Aether and SNAPSHOT dependencies". Example:
mavenRepo "http://myrepo", {
updatePolicy "interval:1"
}
I'm using 2.3.7 and seemed to experience a similar problem. Using a SNAPSHOT plugin should be what you want during development. One workaround solution I used was to delete the SNAPSHOT release from Artifactory and then after building a new SNAPSHOT the plugin change was recognized. I am guessing you are using the Maven build which is now the default you could try switching to the ivy build and see if that helps. A JIRA should be created if you are able to recreate this. I believe this is an issue and I do not recall this when working with an older version (2.1.5) and using the ivy build.
I have tried simple:
mvn clean install -Dmaven.test.skip.exec=true
switching from Maven2 (2.2.1) to Maven3 (3.0.4 - 3.0.3).
But time used for build by Maven2 was lesss! For project that build by Maven2 near 16 minutes, on Mave3 - near 20 minutes.
But, also on stackoverflow I found than Maven3 has better performance. Should I create another local repository for Maven3 (I used old created by Maven2) or use additional options?
Thanks.
Maven 3 should be faster than Maven 2. Of course, there's always the possibility of a performance regression for some edge cases. I'm not sure where the problem is in your case but I'd start by seeing which phase takes longer and comparing that to the Maven 2 build, for instance:
is this a multi-module or a single-module build?
does the build contain non-standard build extensions, for instance the maven-bundle-plugin?
does the build use the latest versions of the plugins? The maven-compiler-plugin brings nice performance improvements for multi-module projects in version 2.4.0
does the build reference artifacts with version ranges? I recall there were some troubles in terms of performance with early Maven 3.0.x versions
are all plugin versions fixed in your POM? It is possible that Maven 3 brings in new plugin versions which have performance regressions
Once you narrow down the root cause you can either fix it yourself - if possible - or submit a bug report to the maven plugin or maven core.
You can try the -T option of Maven 3 which offers the possibility to execute parts of the lifecycle in parallel.
excerpt from the --help output:
-T,--threads <arg> Thread count, for instance 2.0C
where C is core multiplied
But it depends on which plugins versions you are using if they already up-to-date and correctly marked with #threadsafe. But sometimes it's worth a try.
I have an artifact that should be built for several target platforms:
Linux x86
Windows x86
ARM11
Unfortunately due to the lack of crosscompilers, it is not possible to create all versions of the artifact in one go.
Using other words, the goal is to have in the repository something like this
artifact-1.0.0-linux.zip
artifact-1.0.0-windows.zip
artifact-1.0.0-arm11.zip
artifact-1.0.1-linux.zip
artifact-1.0.1-windows.zip
artifact-1.0.1-arm11.zip
...
Note that the versions are in sync. How to accomplish this?
The thing is that the release process upgrades version of the pom.xml after every build. So by building consecutively on various platforms I can achieve having
artifact-1.0.0-linux.zip
artifact-1.0.1-windows.zip
artifact-1.0.2-arm11.zip
artifact-1.0.3-linux.zip
artifact-1.0.4-windows.zip
artifact-1.0.5-arm11.zip
...
but this is not what I am looking for.
I could
run on Linux
mvn release:prepare release:perform -DpushChanges=false
(with pushChanges set to false release won't increase version number in SCM)
and then run on Windows
mvn release:prepare release:perform
(this will increase the version number)
But then the responsibility to trigger the release processes on various platforms in the proper order lies with me. Is there a way maven can help me with this?
Do you have any suggestions?
Thanks
PS. Note that this is not a question about how to organize into modules. It is about how to synchronize release processes of a single artifact on multiple platforms.
Have you found a solution for this yet?
It's good to know I'm not the only one fighting with Maven :-)
Anyway,
Are you allowed to deploy a released version to nexus?
I'm thinking, you could do this:
1 - Do a "mvn release:prepare release:perform" from a windows machine - that should get artifact-1.0.1-windows.zip into nexus.
2 - Checkout the artifact-1.0.1 tag from source control
3 - Do a "mvn deploy" from linux and arm11 (whatever that is :P) - that should get -linux.zip and -arm11.zip into nexus as well.
Though, I believe that depending on how nexus is configured it won't let you redeploy anything with the same GAV (even if the classifier is different)
As I see, you use classifiers (artifact's file name suffix) like linux, windows or arm11 to distinguish various artifact's releases, intended for specific platforms. So, if you create multi-module project managed by Maven, where modules would be artifacts with same groupId, same artifactId, same version (probably inherited from their common parent), but different classifier, you'll get exactly what you want. In such case, you always release your multi-module POM (usually it is common parent for its modules as well) to have all modules released at once. Assuming same-version-for-all-modules-policy (which seems to fit pretty well here), you can basically execute:
mvn release:prepare release:perform -DautoVersionSubmodules
and that's it. You will get artifact-1.0.0-linux.zip, artifact-1.0.0-windows.zip, artifact-1.0.0-arm11.zip artifacts released. Next development version will be set to 1.0.1-SNAPSHOT for all modules (via inheritance from parent).
You helped me out with your question...I didn't know about the pushChanges=false option.
Using Jenkins you can set up a job on each platform that performs the maven release in series using the "Trigger builds remotely (e.g., from scripts)" feature. If you desire, you can use a Parameterized Build to choose which version to build (If you use that, then you need the Parameterized Trigger Plugin to trigger the build on the other platforms).