Skipping a Maven module that's already been published to Maven Central - maven

Let's say I have an aggregate Maven project. com.example:foo:1.0.0 is the aggregate parent POM, and it contains the child project com.example:bar:2.0.0. I publish them both to Maven Central using the nexus-staging-maven-plugin. Note that I do not use dependency management in the parent POM for the version of com.example:bar:2.0.0, even though it is a child project. That is, the two versions are not tied together.
I also use com.example:foo:1.0.0 as the parent POM in other projects, so I would prefer that its coordinates don't change unnecessarily (e.g. be published multiple times with different coordinates, even if the contents have not changed).
It turns out that com.example:bar:2.0.0 changes quite frequently, so I want to release com.example:bar:2.1.0. But I will be building from the aggregate parent POM in that repository, com.example:foo:1.0.0. Must I increment the version of the parent POM as well, even though the parent POM has not changed, and even though the versions are not tied to each other in any way? I would prefer to have the nexus-staging-maven-plugin simply realize that com.example:foo:1.0.0 has already been published, skip it, and continue and publish com.example:bar:2.1.0.
This question also extends to a sibling module that has already been published. Is there some way to configure nexus-staging-maven-plugin to skip a module that has already been published, yet continue building and publishing the other sibling projects that have not been published yet?
From this simplified example I'm sure someone will be tempted to answer, "but you shouldn't do it like that". In my more complex example, there are reasons it might be advantageous to do it like I'm explaining; and besides, that response would still leave the actual question unanswered.
I also realize that I could do some tests to see what happens, and perhaps I will, but I'm posting the question here to 1) get an authoritative answer, 2) promote discussion of the options, and 3) leave some definitive answer here for other who might have the same question. Thank you.

AFAIK, the nexus-staging-maven-plugin does not have a user property to detach or ignore certain artifacts.
You may be able to write your own plugin that takes the Maven project and eliminates a certain artifact from it.

Related

Multi Project Maven using single POM

I have various projects (lets say Project 1, project 2, project 3 etc....). They are in different repositories in the BitBucket.
Some of these Projects share the same Versions. I wanted to check if I can use a Super Parent POM ? I want the Projects to listen to the Parent POM for Version changes, is this possible ? Did google around however dint find any useful information on this.
Any pointers will be helpful
Thanks,
You can use one parent POM for all you projects no matter where you store them. The only requirement is that that POM is deployed in a Maven repository and is available in any of that projects. It can be Maven Central or JCenter or your corporate Maven repository like Artifactory or Nexus. Actually, a lot of open-source projects depend on so-called oss-parent POMs. Take a look at Guava, for example, it depends on sonatype/oss-parents. Some companies make their own parents, like FasterXML.
The answer to second question is generally "no". You cannot simply "watch" for the version changes in such parent POMs, unless you:
Own them. The easiest way. You can trigger downstream builds, or fire alarms, or automatically create issues / tickets in children POMs whenever you update parent POM.
Configure you CI/CD to do that. Basically, it's the same as 1, but you just have to watch for the updates and trigger things.
Use third-party service that will do that. Once, there was one called VersionEye, but they are gone. I've heard that Snyk is doing something similar.

What is the good strategy to maintain Maven transitive dependency satisfied

I recently encountered a difficulty to find back a transitively dependent Maven artifact when building our product, which triggered me to think what is the correct strategy to deal with the situation.
In my product building CI, I need to use a plugin called Maven-Unix-Plugin, which is visible to us. This plugin transitively depends on function-java, which is not visible to us.
We have a Nexus repo, which proxy to the Maven repo. So, in the ideal situation, we don't need to store either maven-unix-plugin or functional-java.
However, I found the expected version of maven-unix-plugin still exists in Maven repository, but its dependent version of functional-java disappeared! More ironically, for all versions of maven-unix-plugin, whose dependent version of functional-java disappeared! In short, the maven-unix-plugin is not usable anymore!
In simple, this sounds an integrity problem of Maven repository. However, my major thinking is how we can avoid this on our side? Now, I managed to find back the old versioned functional-java and put it in our Nexus. However, first of first, it is impossible for us to figure out all of the transitive dependents and put all of them in our Nexus. The ideal picture of Maven is we should NOT be required to do that!
Of course, if we continuously build and maintain our system (and keep updating the dependency version ideally), we should have not faced this problem. However, we are a very small team to maintain a long list of huge legacy systems. The last build for this product is actually 2 years ago!
Any brilliant insights what is good strategies for this kind of headaches to happen in the future?
First of all, MavenCentral very rarely removes artifacts, and only if absolutely necessary. So this problem is likely not to hit you again.
If you want to make sure that this problem will not come again, make sure that you backup the storage of your Nexus repo. All artifacts that are drawn from MavenCentral through your Nexus will be stored in your Nexus storage. So even if MavenCentral is completely wiped out tomorrow, they will still exist in your Nexus.

Maven release and recomposed POM family

I'm having some issues running the Maven release plugin in my company's specific maven structure. Let me explain the concept of recomposed family I'm referring to. My projects are multimodule projects, where each module may have a different parent than its natural father.
project/
pom.xml (the natural multimodule reactor father) (I list as modules all that follows)
module1/pom.xml (my parent is NOT ../pom.xml, I'm a half sibling)
module2/pom.xml (my parent is ../pom.xml, I'm a natural child) (I have a dependency on module1)
project-war/pom.xml (my parent is NOT ../pom.xml, I'm a half sibling)
The reason we adopt this "foster parent" strategy, is that we want to activate some plugins by default for some specific "adopted siblings". For example, every WAR projects needs to define a specific maven-resource-plugin execution ID. Since we have about 80 WARs to generate, imagine the maintenance if we are to add an extra execution step to ALL WARs. This works well for development purposes, we do have valid and running SNAPSHOTs building and deploying.
Now that we want to release, the maven-release-plugin seems not to like this specific structure. In short, since module2 needs module1, but module1 has a different father, release plugin keeps module1 as a SNAPSHOT.
My question here is, has anyone manage to release a projects with recomposed family members? Is there any configuration that I need in the release plugin to enable a full release of such projects?
Violating the inheritance between modules are parent is going to give you more problems than anything else.
Your only options here are either:
fix the parent-children model so the release plugin can do its job (and then move those module activations to the children where you want it)
do the tagging, changing of versions, build+release (mvn deploy , and optionally also site-deploy) manually
After some further tests, here are my conclusions about this issue.
The recomposed family CAN be tackled by Maven on a simple condition: ALL members of the family are present in the reactor.
That would mean having a "super-reactor" that has a reference to both the project you want to release, and the parent poms that may be declared by some modules. Of course, the release plugin will then release everything in this super reactor. If you have many projects that all refer the same parent projects, you should release them in one shot.
Moreover, for the build model to be generated correctly, all relative paths must be right. In my specific case, we wanted to avoid such a thing, I guess we are back to setting a fixed folder structure.
It could be handy to exclude some projects from the release plugin, but of course that creates a potential instability.

Is there a way to undeploy a maven snapshot?

I have some snapshots in a maven snapshot repo that I wish to completely delete. I want to delete these artifacts so that team members will be unable to resolve them if they attempt to continue to use them (they were moved to a new group). Is there a way I can undeploy them from mvn or is this a task that only an admin of the mvn snapshot repo can take care of?
While you can delete it from your server, you can't really stop them from using it; if they have a local copy they will continue to resolve it. You don't really want to block them either - the whole point of maven is a declarative representation of what to use. If they want to build a legacy version of their code for whatever reason (testing, reproducibility, roll-back,...), this would likely block that.
You could push a new snapshot and flag all the code as deprecated so their complier complains (assuming they update).
Now for new projects or updating existing ones we use a common parent POM that uses a dependency management section so that keeps things in pretty good shape. But you have to make sure they stick with your parent pom.
Others have done some work with the enforcer plugin.
It seems people have been talking about this for years here:
https://jira.codehaus.org/browse/MNG-3952
and here:
http://maven.40175.n5.nabble.com/Deprecating-and-banning-artifacts-with-repository-metadata-td124274.html

Automating Maven artifact releasing

For a project with a large number of Maven artifacts (both internally generated as well as external ones), how does one go about automating the releasing of the internally controlled artifacts as part of an overall product release.
Things to be aware of about this question, we use Jenkins and the Maven release plugin. So the operation of releasing a single artifact is automated (albeit the operation to kick-start the process is manual). However the process of releasing all the changed artefacts over the course of a release is not automated (i.e. one has to manually kick-start the release of each artifact). Part of the problem is that almost nothing is released until the end of the release, prior to that everything remains in SHAPSHOT. We have a huge number of components as well as numerous applications/services (over 30) which rely on the plethora of components. So it is not just the case of picking a component and releasing, there are release dependency hierarchies that must be followed (i.e. start at the bottom releasing components that do not use other components and then work your way up until all the applications/services are released).
It is also worth noting that we use two common parent poms which, for the most part, control the versions of the external artifact dependencies and the internal component dependencies. Some pom files for components and applications may override this, but this is (or should be) an exception and should be for a good, but temporary, reason. So when an internal artifact is released, the version in the corresponding parent dependency pom should also be updated.
The product has a release number (of course), however the various pom files technically do not share this version number. While this is not strictly true, the idea as that when parts of the software are set to end-of-life, they will not be updated in the future, thus while a limited number of artifact versions match the product's version at present, this will eventually not be the case.
Any thoughts on ways to get this process automated would be greatly appreciated. Also if you feel what I have described seems to be a crazy way to manage the software, then please provide a comment. Thank you.
You might be able to make use of the Maven Versions plugin which can help formalise versions for projects.
For example, the use-next-releases goal may allow you to release the lowest level of project and then more rapidly bring those released versions into their dependencies.
There may also be scope to use the use-next-versions goal if you fancy releasing components as necessary and simply bring your projects to the "latest" version thats been formally released.

Resources