New to Maven.
Ok so I used Maven to package up my project, but one of the files had some test information in it. I would like to change that file but I'm at a standstill as keeping the same version number of the project.
I don't know what to do! Are these my options and what's the best way to do this?
Change the file and do a new build of the project which would increment the build by one.
Example: Build is at 2.0, it would move to 2.0.1 or 2.1
Remove the project from Maven and do a rebuild of the last project but with the new changes.
This is what I want to do but don't know how to remove the project from Maven and reset everything to do a rebuild
Open to suggestions???
Thanks
What exactly do you mean by "remove a project from Maven"? You mean from a public Maven repository?
You should probably bump up the version, as most projects do, when there's an "oops" moment like that. The release notes would ideally state why there's been a new version. Ideally a public notice as well.
Otherwise, you risk people getting the wrong version, or something that they have the fixed version, or whatever. For example, I use the Maven offline option (i.e., -o) pretty regularly so I don't grab the latest snapshots.
I used Maven to package up my project, but one of the files had some test information in it. I would like to change that file but I'm at a standstill as keeping the same version number of the project.
Maven never re-downloads released artifacts with a fixed version (as opposed to a SNAPSHOT version) once they have been downloaded (unless you delete an artifact from your local repository of course but you obviously can't rely on that). This is the only way to guarantee reproducibility (if I rebuild later, I get the same behavior). And in the same spirit, you actually can't re-release an artifact with a fixed version. This is the only way to guarantee consistency (everybody gets the same stuff).
So you'll have to change the version if you want to re-release your project.
Note that if your project is under active development, you should use a SNAPSHOT version. Here is what the Maven: Definitive guide writes about them:
3.3.1.2. SNAPSHOT Versions
Maven versions can contain a string
literal to signify that a project is
currently under active development. If
a version contains the string
“SNAPSHOT,” then Maven will expand
this token to a date and time value
converted to UTC (Coordinated
Universal Time) when you install or
release this component. 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. In other
words, when you deploy a snapshot, you
are not making a release of a software
component; you are releasing a
snapshot of a component at a specific
time.
Why would you use this? SNAPSHOT
versions are used for projects under
active development. If your project
depends on a software component that
is under active development, you can
depend on a SNAPSHOT release, and
Maven will periodically attempt to
download the latest snapshot from a
repository when you run a build.
Similarly, if the next release of your
system is going to have a version
"1.4", your project would have a
version "1.4-SNAPSHOT" until it was
formally released.
As a default setting, Maven will not
check for SNAPSHOT releases on remote
repositories. To depend on SNAPSHOT
releases, users must explicitly enable
the ability to download snapshots
using a repository or pluginRepository
element in the POM.
When releasing a project, you should
resolve all dependencies on SNAPSHOT
versions to dependencies on released
versions. If a project depends on a
SNAPSHOT, it is not stable as the
dependencies may change over time.
Artifacts published to non-snapshot
Maven repositories such as
http://repo1.maven.org/maven2 cannot
depend on SNAPSHOT versions, as
Maven's Super POM has snapshot's
disabled from the Central repository.
SNAPSHOT versions are for development
only.
Related
Here is my current understand of how Maven handles dependencies.
When a dependency is being actively worked on Maven attaches the "-SNAPSHOT" to the end of the version. ex) 1.1.1-SNAPSHOT. These snapshots are uploaded to a remote repository that is specifically responsible for snapshots. The same remote repository has a section for released versions of the packages. Now when a project has the dependencies updated, Maven pulls the most recent version of a package into the local repository. ONLY SNAPSHOTS are updated depending on the time stamp on the the snapshot. If Maven pulls down a release version (ex: 1.1.0) it will never look for another package with the current version.
Now my questions are:
What are the flaws in my understanding? Am I missing a conceptual piece?
When a package moves from a SNAPSHOT to a release version, how do the pom.xml get updated to reflect the released version of the package? Is this a manual process?
Lastly, if a package is released, we'll use the example from above, 1.1.1 is released. Is 1.1.2-SNAPSHOT created or 1.2.0-SNAPSHOT created, and is this the version that will be updated in the poms?
Snapshots are currently in development versions and could be not stable.
We are old fashioned company which still use svn:
The development is going in the trunk and version in pom files are snapshots (we have dependencies to some opensource libraries that have fixed version, and we update them as soon as new release happens and we are confident about switching)
As soon as we are going to release we are branching trunk and changing versions in pom to corresponded fixed one (some companies could mark them with suffix -rc)
Release (Companies that use -rc will change version in pom to fixed one)
Please take a look to release maven plugin to skip manual version changes.
I hope this answers some of your questions.
About the versioning answer - it depends. Please read about it more here:
http://en.wikipedia.org/wiki/Software_versioning
Best Practice: Software Versioning
I get what internal libraries are. But what is the purpose of a snapshot repository in archiva?
Libraries - private releases
Snapshots - private builds?
I have archiva set up and working with LDAP, but I am wondering why I need a snapshot repository. What purpose does this solve? Why is this used in development?
Also, lets say I update a library in the internal repo. Does this automatically update in the project POM files which use Maven, or I must update those poms to use the new JAR version?
Usually before releasing a maven project, the version is -SNAPSHOT.
So with such repositories you can share fresh SNAPHOT of your project for other people in your team to test or with a ci server.
Snapshots is maven idea to give version number as -SNAPSHOT , its under development it can be change any time.
Internal repository is the release repository with fixed version number. You can modify the SNAPSHOT, but That artifact never changes after it is released.
When we use internal, if dependency does not found inside it, then it will download it from central repository of maven. where as in snapshot it does not.
Question says it all, I believe.
Please and thank you
GC
The Maven assembly plugin is dedicated to create highly customizable package, such as zip, tgz... files. You define, in a descriptor, the content of the final package (or assembly), by including files, directories, dependencies, etc.
The Maven release plugin is dedicated to the release process, which includes several repetitive manipulations and operations. For example it will do some checks (is there any uncommited changes, some SNAPSHOT libraries used and so on), prepare your Source Control Management (CVS, Subversion...), modify the pom versions (to get rid of the -SNAPSHOT), commit the modified pom.xml, etc.
You can have an example of a release process here.
EDIT
Regarding your question about -SNAPSHOT. For Maven, a fixed version is linked to a dependency that never changes. For example, two libraries with the same fixed version must be identical. So for example, foo:bar:1.2.3 is strictly identical to another foo:bar:1.2.3
This is not necessarily the case for a -SNAPSHOT version. The SNAPSHOT keyword indicates that the current library is under development. Thus, two versions of foo:bar:1.2.3-SNAPSHOT and foo:bar:1.2.3-SNAPSHOT may not be identical. A timestamp is used by Maven to check which one is the newest.
So in the normal release process, you have your 1.2.3-SNAPSHOT version, which is not in development anymore. So before releasing this library, you will have to fix the version, i.e. move your pom.xml version to 1.2.3.
This modification can be done by simply modifying the pom.xml versions, or it can be managed by the Maven release plugin (or also with the Maven version plugin).
I hope the explanations are now clear regarding this particular aspect of Maven.
I am developing code actively, with my developing team. When we release to our customers, I would like to provide jars without the -SNAPSHOT so they only need to update when a new dot version is created.
This there a maven plugin that provides this functionality. I know there is because everyone else must do it some how. I doubt it is manually.
I would appreciate answers to be explicit as possible.
Please and thank you.
Some plugins can help here, as already mentioned in this answer and in the comments of this one: the Maven Release Plugin if you want to fully automate the release and/or the Maven Versions Plugin.
With the Maven Release Plugin
Releasing a project with the Maven Release Plugin is done in two steps: prepare and perform and here is what the documentation writes about the release:prepare goal:
Preparing a release goes through the
following release phases:
Check that there are no uncommitted changes in the sources
Check that there are no SNAPSHOT dependencies
Change the version in the POMs from x-SNAPSHOT to a new version (you
will be prompted for the versions to
use)
Transform the SCM information in the POM to include the final
destination of the tag
Run the project tests against the modified POMs to confirm everything is
in working order
Commit the modified POMs
Tag the code in the SCM with a version name (this will be prompted
for)
Bump the version in the POMs to a new value y-SNAPSHOT (these values
will also be prompted for)
Commit the modified POMs
In other words, the Maven Release Plugin is exactly doing what you're asking for.
With the Maven Versions Plugin
If you don't use the Maven Release Plugin, the Maven Versions Plugin can be helpful. In particular, the following goals:
versions:update-parent updates the parent section of a
project so that it references the
newest available version. For example,
if you use a corporate root POM, this
goal can be helpful if you need to
ensure you are using the latest
version of the corporate root POM.
versions:update-child-modules
updates the parent section of the child modules of a project so the
version matches the version of the
current project. For example, if you
have an aggregator pom that is also
the parent for the projects that it
aggregates and the children and parent
versions get out of sync, this mojo
can help fix the versions of the child
modules. (Note you may need to invoke
Maven with the -N option in order to
run this goal if your project is
broken so badly that it cannot build
because of the version mis-match).
versions:set can be used to set the project version from the
command line.
versions:commit removes the pom.xml.versionsBackup files. Forms
one half of the built-in "Poor Man's
SCM".
versions:revert restores the pom.xml files from the
pom.xml.versionsBackup files. Forms
one half of the built-in "Poor Man's
SCM".
I mentioned several goals but the "most" interesting is probably versions:update-child-modules here. It would allow to change the version in the top parent pom and then to automate the update of the child. See Fixing a multi-module build for an example.
Can't help more, you need to experiment yourself now. Good luck!
References
The Maven Release Plugin
The Maven Versions Plugin
I'm using maven 2.2 with nexus 1.4.0
Let's say I have a pom-structure like this (with corresponding versions)
parentproj, v1.0.1
- childproj1, v1.0.2
- childproj2, v1.0.7
childproj1 and childproj2 represent different parts of the application (e g gui and backend) and I want to be able to keep their versions separate so that I can release a new version of the backend without having to release a new version of the gui.
Now, to deploy this structure to Nexus it would be convenient to go to parentproj and say
mvn deploy -DperformRelease=true
which would deploy all artifacts to the Nexus realease repository. This works fine the first time I deploy it, but the second time I run into problems: let's say that I made an update to childproj1 so that we now have the following versions:
parentproj, v1.0.1
- childproj1, v1.0.3
- childproj2, v1.0.7
In this situation Nexus will not let me do mvn deploy from parentproj, since it already has a copy of childproj2 in the 1.0.7 version. Nexus will say "Resource, illegal request:Repository with ID='releases' does not allow updating artifacts." This is fine, I don't want to update existing versions by mistake.
But I guess that what I would like to do is to be able to tell maven something like "deploy only those artifacts that have versions that are not already present in the release repository".
Is there a way to do this, or would I have to deploy each project by itself?
In my experience, it has been easier to deploy everything, and often use the same version number for all the components. For example, if my team is working on version 1.0.7, all the submodules have the version number of 1.0.7-SNAPSHOT, until we release, even if no code has changed in certain modules. Then when we deploy, we would deploy the whole application. I think it has several advantages over a piecemeal deployment. First, if you every have to rollback to the last stable version, you just have to rollback to 1.0.6 for all modules--you don't have to remember that the backend was 1.0.3 while the GUI was 1.0.6. Second, it ensures that all the components are compiled correctly against each other and have been tested as a logical group.
Sorry, I know this isn't a specific answer to your question, but, at least in my team's case, it was useful to think slightly differently
First of all, I think you should distinguish between parent project and aggregation project. Parent projects should be used for those settings that are common to several projects, e.g. dependencies' versions; aggregation projects should be used in order to build at the same time a group of projects, e.g. a set of jars and the war that includes them.
The two kind of projects are best kept separated. The parent project usually does not change very often and when it does it is usually best to release new versions of all the projects that depend from it; the aggregation project's only purpose is to drive the build of a bunch of projects, so its release number should probably change whenever one of the projects it contains needs to be released.
Once you've separated parent from aggregator you're in a better position to choose whether to follow John Paulett's advice and keep everything at the same version number or to try and change each project's version number only when you actually need to release it. The first option is simpler and less error prone, but causes you to release new version of libraries that haven't changed. This might not be acceptable if, for instance, you need to ship patches rather than full releases. The second option is more complicated and error prone, but causes your release numbers to match the evolution of your software. The Maven release plugin and the Jenkins continuous integration tool may be of help there, I think you should check them out. Also, see if you can upgrade Maven to at least version 2.2.1 and Nexus to a more recent version.
I would suggest you Artifact Exists Maven Plugin (https://github.com/chonton/exists-maven-plugin). This wonderful thing requires only to be mentioned on the parent.pom, and will automatically skip the install and deploy phase for all release artifacts, that already exists in repository (Nexus or Artifactory). And still deploy the Snapshots (this is configurable).
Example:
<plugin>
<groupId>org.honton.chas</groupId>
<artifactId>exists-maven-plugin</artifactId>
<version>0.0.6</version>
<executions>
<execution>
<goals>
<goal>remote</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
I would suggest that if you plan to maintain, build, and deploy the modules independently, you should consider setting up separate CI and mvn deploy jobs for each. Having independent mvn deploy jobs will give you the behavior you are looking for out of the box. This means not using the aggregator pom (parentprj) to attempt building and deploying these modules.
If you want to do everything from the aggregator pom, like build and deploy, then I would suggest following John's answer and keeping all the version number in sync.
It just depends on how your team wants to look at the code base. If you want to keep things in a true modular fashion, you should be using your maven modules like building blocks, treating them differently, until you are ready to put the whole app together. If your app is more monolithic in nature, treat it as so and keep things in sync. This doesn't mean you still can't break out separate maven modules for maintaining code-base modularity, just recognize they don't have any value outside the context of your larger app.
A good way of making this decision is asking yourself "Will any other projects/apps need to reference this module as a dependency?". If so, it is best practice to build, version, and deploy it independently. If not, I don't see any pitfalls to making the versions match up.
Clearly this need is not addressed by maven, neither by Nexus or archiva.
For now it can only be addressed by additional tricks setup by the build manager like the ones suggested in previous posts.
In an ideal world
the pom would include
. both the release version and the snapshot version of the module
. a definition of the files which, if changed, justify the use of the snapshot version
. the source control management system reference of the released module
dependent modules poms would add in the appropriate dependency section the release version info next to the snapshot version info so that it links to the snapshot library if present in the repo and the release library otherwise
the maven reactor would have an option to read both the dependency hierarchy and the file changes info (scm diff) to know whether a given module is to be used in its release or snapshot version.
the release plugin would by default skip the releasing of the modules whitch still can be used with their release version based on the file changes and the dependency info.