Our team manages Java projects using Maven. We have a policy that all code on the master branch of a repository should:
itself have a -SNAPSHOT version (releases are created using the Maven Release plugin)
have Maven dependencies only on releases and never on -SNAPSHOTs.
This has an unfortunate consequence in IntelliJ IDEA (version 15, build 143.1821.5). Suppose Maven artifact A depends on some release version of Maven artifact B, say 1.2.3. The current code for B on master, though, will be something like 1.2.4-SNAPSHOT. If I load the source for both A and B in IDEA, go to a class in B which is used in A, and do a Find Usages (Ctrl-click the class name or Alt-7), no results are found. If, however, I navigate in the IDE to the decompiled class file for the 1.2.4 release and do Find Usages, it finds the usages in A.
I understand why this happens --- the -SNAPSHOT version of the code really isn't being used by A --- but this degree of pickiness makes Find Usages nearly useless across Maven artifacts. However, I seem to remember at some point in the recent past IDEA's Find Usages wasn't so picky. Unfortunately Googling hasn't turned up anyone else mentioning this problem or a mention of a change in IDEA behavior, so now we are thinking we just imagined the previous behavior.
So, does anyone know how to get IDEA to ignore version mismatches on Maven modules when doing Find Usages? Was there some setting we had enabled before that we now can't find?
I think you're doing this incorrectly.
By definition, the MASTER branch should be a released version (no -SNAPSHOT).
You want to talk to your team and review your build and release processes.
Have a read about the git-flow branching model for some more information about branching strategies.
Related
Consider a project that is used in other projects, and this project has version 1.0 and is present in the Nexus.
After that, some changes are done in this project.
Now there are two solutions:
Increment the version of the project to 2.0, and delete the version 1.0 from Nexus. When the developers try to get the dependencies from the Nexus with version 1.0 they will get an error that this version does not exist and need to change the version to 2.0.
Change the functionalities of this project and inform the crew that some changes are done, but this is not the practice at all.
Is there any functionality in Maven and Nexus to simplify this task and make this all happen in the backend so the developers can't do anything, or is this not possible?
If you have an old version of an artifact that must not be used anymore because it has some dangerous bug, or it does not work with the new database structure or something like this, it may be advisable to move it to some non-public Nexus repository (and also delete it from the local repository of the build server), so that nobody can use it for release builds (people can use it for local builds, but this is usually not dangerous).
If you want to manage standard versions throughout your company, it is a good idea to have a parent pom or some boms which collect versions in a <dependenyManagment> section and can be included by the developers. This way, you only need to inform them to change one version number (namely the one of the parent pom or bom) instead of many.
Still, you are left with the problem that people do not read company newsletters. I know the problem that many developers of jars compile and test their source code against very old versions of their dependencies while the war/ear (that includes the jar) uses new versions.
I have setup a multimodule project with maven.
hierachie is
- parent
-- module 1
-- module 2
-- module n
I am wondering, how I can release just one single module of this project in Jenkins.
Would appreciate any comments.
Thank you
No problem with that, go for the maven-release-plugin and release the modules of interest only.
You should start with the parent. Afterwards, go for the others (assuming inheritence is in place, and these are not submodules of parent). Moreover, as there might be dependencies between modules, make sure to follow the rule, that: there are no SNAPSHOT dependencies on the module you're about to release.
For deeper understanding, check the official docs of maven-release-plugin, or go for the link (that seems to summarize/detail steps on release, even the background things happening).
Steps to be done on each module are:
preparation for release
performing a release
Moreover, as you're interested in Jenkins release, you should go for: non-interactive release
Well, release plugin might be a pain to use properly/get used to, but once it's setup, moreover assuming Jenkins jobs would be created for the purpose, things should get settled and releases smooth.
I have two multi module projects. One is the main project tree. The other project tree pulls in the artifacts (WARs, JARs, etc) from the first project. They each have their own separate parent pom.
I would like to keep their version numbers identical. Project 2 has a dependency management section that has the artifacts from project 1 in it. The problem with this is that I can't release the project due to snapshots.
For example. The version number (for both projects) is 3.4-SNAPSHOT. I can release a version 3.4 of project 1 and all the pom versions will be set from 3.4-SNAPSHOT to 3.5. When I go into project 2, I want to do the same exact thing. The hitch is that dependencies of project 1 are at 3.4-SNAPSHOT and I can't figure out how to automatically get them to be 3.5. It's like I want the dependencies to be updated to the release version, before actually releasing.
I understand that if I make both trees extend from the same parent pom, the maven release plugin would detect the dependencies as submodules and update them automatically.
I read a little bit about the versions plugin but I didn't like the use-latest-versions part of it (it seems way to dangerous). The Update-properties seemed promising but it upon a second cursory look, it looked like the use-latest-versions plugin packaged slightly different.
Also, I tried just using ${project.version} but that's basically the same as putting 3.4-SNAPSHOT in as the dependency - it'll error saying it can't release due to snapshots since the version actually hasn't been updated yet.
The way you have the projects configured they are totally independent. You might as well be asking for the version of your log4j dependency to be the same as your current project B version.
While it won't be automatic, you should replace the versions of all references to Project A within Project B to use a property that is defined in the parent pom for Project B. Then, when you release Project A, you only have to change one pom so the project.a.version property is now the released version instead of SNAPSHOT. After the release of B you could then change it back to ${project.version} to keep them in sync.
As you admit, the right answer here is to re-arrange your project to have a common parent. Anything else is just a workaround.
However, it looks to me like versions:use-releases might achieve your goal. You can specify an includes list to ensure only project 1 dependencies are updated.
If you wanted this to be automatic, you could consider binding this goal to one of the lifecycle phases prior to compile.
Edit: sadly this looks like its not possible. At least, that's how I understand by the "Executes by direct invocation only" mentioned at the top of the page.
We check all of our source code's dependent third-party JARs into source control along with our source code. When needed, we manually download updates to third party JARs and replace those JARs that are in source control with the newer versions. We haven't felt the need to use Maven yet as this process seems simple enough for us. But are we missing something of great value by not using Maven? Or does our scenario not warrant using Maven?
"JARs dont change much", I hear this all the time.....
Storing jars in the SCM is simple in the beginning of the project. Over time the number of jars gets larger and larger.... Wait 2 or 3 years and nobody remembers where the jars came from, what their licensing terms were and most commonly what versions are being used (important to know when analysing security vulnerabilities).....
The best article I've read recently making the case for a repository manager is:
http://www.sonatype.com/people/2012/07/wait-you-dont-have-a-repository-manager/
A little irreverant, but does make a valid point about the kind of technical inertia one encounters all the time.
Switching a project team from ANT to Maven can be scary.... Maven works quite differently, so I find it is best deployed with greenfield or adventurous project teams. For the old-school ANT users, I recommend using the Apache ivy plugin. Ivy allows such teams to outsource the management of their dependencies but keep the build technology they're comfortable with.
Ultimately the biggest benefit of using Maven are not dependency management. It's the standized build process. I've seen several failed attempts to create a "standard" ANT build process. Problem every build engineer has his opinion on what the standard should be.... Maven's approach of forcing users to write build plugins may appear restrictive in the beginning, but just like the iPhone eventually developers discover "there's a Maven plugin for that" :-)
When it comes to dependency management Maven really can be quite valuable. As Mark O'Connor suggests, running a local repository manager would likely be better than checking the artifacts into source control.
There are many tools (like m2e in eclipse) that can help with dependency management and provide valuable feedback on which modules or dependencies require which other dependencies. Maven will also make sure to get the appropriate version of a dependency even if different modules depend on different versions of a given library. That will help prevent duplicate versions of the same jar showing up in your deployed project as long as they have the same group and artifact id.
Even for a very simple project I don't think I would resort to checking dependencies into the source control system.
It's not only about 3rd Party Libraries. Mostly if you have multiple repositories. In our case, we had four repositories with lots of inter- and intra-dependencies.
Actually I started this answer and then I had to go for 15 minutes to talk to some colleague about a problem happened after someone forgot to update the .jar of one project in the other's lib directory.
And it looks more professional :)
I'm working on a rapid project, of which, I'm directly working on a module that is continuously changing. Others have a direct dependency on the module, and as such, I stubbed out the public interface and deployed it to our local Nexus repository as 0.0-SNAPSHOT for use.
Now that I've almost completed my first iteration of the module, I've attempted to redeploy the updated artifact. Reading about snapshots, others claim that a snapshot should represent the current head trunk. Is this true?
Maven automatically increments my snapshot version upon redeploy - so, going from 0.0-SNAPSHOT, I'm still at 0.0-SNAPSHOT, only, it's iteration 3 or 4 of the same snapshot. When should I roll over to 0.1-SNAPSHOT? Is there a plugin I can use to automate the version change, instead of manually editing my pom?
After integration testing and the deployment of our first system release, 1.0-RELEASE, how should my module progress? Should I move my module to 1.0-SNAPSHOT and continue thereon? Is there a methodology one should follow, or is it left to the discretion of the developer?
The X.Y.Z-SNAPSHOT notation identifies temporary versions leading up to release X.Y.Z, so you usually do not move from X.Y.Z-SNAPSHOT to X.Y.Z+1-SNAPSHOT unless you release X.Y.Z. If you adhere to this convention the maven-release-plugin may help you with the full release process.
Note that the most common Maven convention uses 3-number release identifiers without any suffix (i.e. no -RELEASE). Suffixes are usually used to distinguish variants of the same release.
Maven is all about conventions, so there's little chance you'll go very far without reading about it: This book is a good starting point.
For updating your POM version without manually updating, you may take a look at Maven Release plugin (Although I wrote myself a little script to do the POM update as I find Release plugin don't fit that good in my work flow)
It then come to your version number issue. It is more a release procedure issue. Normally a planned release is denoted by increment of Major or Minor version in the version number. SNAPSHOT version denote that certain release is in progress. For example, I will prefer doing something like this for your case:
Assume I am planning to release first iteration as 0.1, then I will make my head trunk in SCM (e.g. trunk in SVN) with 0.1-SNAPSHOT as version. Which denotes that all development is in fact contributing to release of version 0.1. Upon finish, I'll update the POM version from 0.1-SNAPSHOT to 0.1, perform an actual release of version 0.1 (including release branching, tagging, deploying the artifact), and then change the POM version to SNAPSHOT of next planned release (for example, 0.2-SNAPSHOT).
Similarly, after releasing 1.0 (or 1.0-RELEASE in your example), POM version in head trunk should then be updated to snapshot of your next release version, for example, 1.1-SNAPSHOT.
Just bear in mind that there should no longer be SNAPSHOTs of certain version, if that version is actually released.
Understand the way maven interprets SNAPSHOTS is to clear any doubt you can have.
Extract from http://books.sonatype.com/mvnref-book/reference/pom-relationships-sect-pom-syntax.html
For example, if your project has a version of “1.0-SNAPSHOT” and you deploy this project’s artifacts to a Maven repository, Maven would expand this version to “1.0-20080207-230803-1” if you were to deploy a release at 11:08 PM on February 7th, 2008 UTC
First, Let me suggest to stick on maven conventions and change your version to 0.1 as maven archetype:generate propose.
So SNAPSHOT helps others to stay up-to-date easily with your active project. On every compilation, their projects will check new releases of SNAPSHOTS dependencies (based on that pseudo-datetime-version they have on its .m2 directory).
When you finish work on 0.1-SNAPSHOT you deploy an 0.1 and start a 0.2-SNAPSHOT or 1.0-SNAPSHOT