Before the question I'd like to describe the methodology I use.
I have a lot of projects under version control folder, some of them multi maven projects, some of them standalone bundles, some of them maven plugins or archetypes. All jars are snapshot (currently we can not use release artifacts). So for example application A1 depended on bundle B, which depended on utility C, another application A2 directly depended on utility C. When I change code in C I need to update it's version and then update B and A2, then A1. It is really annoying to update all those poms once at week. So I'm looking for some automatic solution that can handle it for me (like if C has new version all depended modules have to be updated).
Does any body have idea?
Thanks in advance
P.S. I thought to make a MOJO which can handle this, but I faced with some difficulty since not all projects has common parent project ...
Sounds like something the versions plugin can handle... http://mojohaus.org/versions-maven-plugin/
This is considered a bad practice, but if you deploy your projects using -DupdateReleaseInfo=true (or with the release plugin), then you can set the dependency version to RELEASE
<dependency>
<groupId>some.groupid</groupId>
<artifactId>some.artifactid</artifactId>
<version>RELEASE</version>
</dependency>
and you will always get the latest release version
If you're using SNAPSHOT-s only, you could always go for parent based projects. Define the versions in a parent and make the children extend it. You can also choose to use versions such as RELEASE or LATEST.
Consider using a Continuous integration engine to watch all projects and build them when changed.
If you use Jenkins you can set it up to provide the built maven artifacts as a Maven repository, which you can then use in your own Maven configuration.
This should be enough - the snapshot mechanism handles the rest.
Related
I'm developing Jenkins' plugin which is dependent on another plugin (specifically MultiJob plugin, but it can be any other one of course).
Obviously, the dependency is found in POM, so I can actually use the classes of it.
The problem: if I'm trying to install my plugin in Jenkins that the dependency is not found in it Jenkins doesn't installs it automatically and upon first usage my plugin throws an exception NoClassDefFoundError, of course.
Question: can I make Jenkins to install my dependencies as prerequisites and if yes, how?
Note: I do see that other plugins somehow cause the dependencies to be installed (Git plugin for instance makes GitClient installed during its installation).
Thanks in advance.
It's been a while since i've raised the question, but if anybody will look for something similar, here is what i've finally came up with:
Since the dependency classes are only needed in case they are really there, i've decided to use Java's lazy linkage behavior and actually refer the relevant classes only on demand.
So practically, made a factory that has a list of class names of interest and every time i need to process some object i'm checking it's class against this list. If matched - the class is loaded and therefore it's okay to init the linking/initiation logic.
Last one, if you plan to use such a pattern do not forget to sign those dependency plugins as optional in your pom.xml.
All our projects are built using maven.
we have centralized some of our main configuration within a super pom.
In order to always have an update version of this super pom (without having to modify the version), we have used the following syntax :
<parent>
<groupId>my.organization</groupId>
<artifactId>superPom</artifactId>
<version>RELEASE</version>
</parent>
The problem is that Maven Eclipse plugin (m2e) doesn't understand this syntax (the RELEASE constant is not resolved).
So, our Eclipse users can't use built-in compilation.
What do you suggest to overcome this problem ?
By the way, we have tried several options from a maven point of view (especially those described here), but the version.RELEASE is the easiest for everybody (except those who are using Eclipse).
EDIT:
Our projects sources are split within multiple SVN repositories.
This super pom is an independent project. It is retrieved through our Nexus server.
You are trying to go into the wrong direction. A release in maven is a particular version like 1.0.0 and it indicates that you have a defined state of that artifact. In your case you super pom has a particular state. If you are trying to define the version to "RELEASE" you are saying my release is always the same but in reallity it's not true.
Usually such a super pom will change over the time lets say today you have defined some particular dependency versions in it (dependencyManagemet). And tomorrow you change those definition. Now the 1.000.000$ questions which state of the super pom is used in a build which has been done today? Ok in that simple scenario you can answer the question but if you have changed the super pom sometime yesterday you can't answer the question accurately.
Furthermore if you try to recreate an artifact of let's say last week you can't say which exact state of super pom has been used at that particular time cause you have no indicator which gives you the chance to see it.
And that's the reason why you need real versions like 1.0.0 or 1.1.0 etc.
I can strongly recomment to use real versions like 1.0.0 etc. but NOT things like "RELEASE" that will creep in the Maven system with its corrdinate group, artifact and version.
Version ranges and expansion indeed do not work for parent artifacts.
Someone advised to invoke the version plugin instead :
mvn versions:update-parent
which does not cover exactly your need, but I am afraid there is no better workaround. Other ideas : using a SNAPSHOT parent pom (not very satisfactory I admit). See also Maven2 cannot find parent from relative path.
I have some related legacy projects that are a mess and I would like to mavenize them as a multi-module project shared on subversion (first multi-module project, we've always had them separate). There are a few key parts 1) webservice, 2) various swing clients, 3) model (w/ persistence from hibernate), 4) core JSE tasks.
I've been messing around for a few days trying to correctly set it up using Eclipse (Helios), Maven (2.2.1), m2eclipse (0.10.0) and Subversion (1.6) for our team. I keep stumping myself or having random errors that force me to backtrack. I'm hoping someone can help me out with some best practices.
Here are some of the questions:
m2eclipse requires a "flat" eclipse project structure. Does that mean I should create a subversion repository for each module? If I do one repository and try to check in from the parent project I'm having a difficult time setting the svn:ignore property on the nested project target (and other) directories.
If I do a module per repository, I seem to be able to check them in ok. The question then is what is the best way to check out via subclipse? Is there a best order? Parent or child project(s) first? Do I need to checkout the parent project and modify the checkout path of the children project to be nested in the file directory that will allow me to then "clean install" from the parent project?
Or, should I abandon subclipse and m2eclipse and checkout and run my maven goals from the command line.
Or, should I just be using the SCM integration with Maven. Or, maybe just not even try to get a multi-module project setup.
What do others do? Does anyone have some documentation (I missed) or some links (Google didn't recommend)?
Thanks in advance for your feedback.
m2eclipse requires a "flat" eclipse project structure.
Hmm, m2eclipse supports nested projects AFAIK (or at least importing a nested project structure). I don't use Eclipse wizards to create my projects though so maybe I'm not aware of something.
Does that mean I should create a subversion repository for each module?
No, no, absolutely not and I wouldn't do that (this will be hard to maintain). However, depending on your projects release cycles, you might have to think about the layout of your repository (single vs multiple trunk/tags/branches), especially if you plan to use the maven release plugin. If some pieces have independent release cycles, then I'd go for several trunk/tags/branches. If you always release them all together (as a single product), then a single trunk/tags/branches should do it. I wrote several answers on the topic that may be of interest:
Migrating to maven from an unusual svn directory structure?
Maven parent pom vs modules pom
How to handle maven versions in a multi module project?
If I do one repository and try to check in from the parent project I'm having a difficult time setting the svn:ignore property on the nested project target (and other) directories.
What is the particular problem?
If I do a module per repository, I seem to be able to check them in ok. The question then is what is the best way to check out via subclipse? Is there a best order? Parent or child project(s) first? Do I need to checkout the parent project and modify the checkout path of the children project to be nested in the file directory that will allow me to then "clean install" from the parent project?
Whatever choice you'll make (multiple repositories or not, multiple trunk/tags/branches or not), it should be possible to checkout the whole project structure in one time (using svn:externals if required). At least, you should try to make it possible (and it is, see the links posted above).
But I repeat, I do not recommend using multiple repositories (unless you want independent revision numbers) and nothing forces you to do that.
Or, should I abandon subclipse and m2eclipse and checkout and run my maven goals from the command line.
I use Eclipse, m2eclipse, subclipse successfully, all well integrated (at least for the build and "check in" part). But I do the initial import and the initial checkout on the command line and then imported
Or, should I just being using the SCM integration with Maven.
I don't use it, I don't have the need for it.
Or, maybe just not even try to get a multi-module project setup.
There is no reason to forbid the use of a multi-modules project setup, multi-modules builds are one of the key part of Maven.
What do others do? Does anyone have some documentation (I missed) or some links (Google didn't recommend)?
Have a look at the links I posted :)
It is a bit tricky at first. The way I've typically seen it setup is like so:
In subversion:
- Parent Project
-- Module A
--- pom.xml (module A)
-- Module B
--- pom.xml (module B)
-- Module c
--- pom.xml (module C)
-- pom.xml (parent project)
Some things to note (you already know):
You have to have the child projects
listed as modules in your parent
project
You have to list the parent project
in your child pom's (as the parent
group, artifact, version)
When you check out the project from
svn, you need to do 'check out as
maven project' instead of the
standard 'check out' (this one can be
a gotcha)
I hope this helps.
I'm about to start working on a web-application and I'll be using Maven. I want the web-application to be an individual artifact. The web-application will end up depending on a couple of self written libraries (for example text-formatting), and each of these libraries should be an individual artifact.
What's the recommended way of achieving this separation while making it simple to code for both artifacts? I was thinking of creating one project for each artifact and import them one by one in Eclipse. However, if the pom for web-application has a dependency pointing at the self written library, I'll end up having to deploy a snapshot every time I want to see if the change I made stopped the web-application from crashing (in example).
I hope you understand what I am getting at. I'll be working with a couple more developers, and we're using Nexus to maintain our shared artifact repository.
I was thinking of creating one project for each artifact and import them one by one in Eclipse.
Yes, that's the recommended way.
However, if the pom for web-application has a dependency pointing at the self written library, I'll end up having to deploy a snapshot every time I want to see if the change I made stopped the web-application from crashing
During development, you can use "workspace resolution" i.e. configure Eclipse to resolve dependencies from the workspace. This way changes are immediately visible from the webapp. This is possible whether you are using m2eclipse or the maven eclipse plugin (and is actually the default behavior for both).
Below, an illustration for m2eclipse:
A good maven plugin for eclipse is capable of "workspace resolution", i.e. it will recognize if the dependency is also present in the workspace, and refer to the other project directly rather than adding a JAR to the build path.
Scenario: The system has number of components, each with its own POM. There are some long dependency chains (A depends on B depends on C, etc.). I want each "non-developer-desktop" build to be a potential release candidate -- if it passes QA, we will deploy it without rebuilding. In other words, I never want to build SNAPSHOT versions as part of my regularly scheduled builds, only versions like 1.3.0.5, 1.3.0.6, etc. I also want to enable the developers to work on multiple components at once.
To forestall some expected suggestions: the Maven Release Plugin doesn't help me ... unless there's some magic way I can have my dependency versions not be SNAPSHOTs in the POMs but still let the developers work on more than one component at once?
How should we manage the project and dependency versions in all of our our POMs? Right now it's just SNAPSHOTs everywhere, which makes things simple for the developers (they started with SNAPSHOTs and never concerned themselves with anything else). But it's worrying at deployment time (builds with SNAPSHOT dependencies are not well-defined, and not reproducible).
I'd like to avoid excessive juggling at build time, but right now I don't see any way around it.
Let's say I have components util, libj, libk, APP, and UI, with dependencies as follows:
libj -> util (libj depends on util)
libk -> util
APP -> libj
UI -> libj, libk
I have development teams working on APP and UI, and they will sometimes need to make changes/additions to some of the dependencies (even util) in order to enable their current work. How should the checked-in POM and dependency versions for each component look?
Edit: I updated the title to refer to Maven 2 instead of 2.0, since it became apparent that I would need to work with 2.1 or better in order to best resolve this.
Try to layout your builds such that modules that need to be developed together are released together. This will let the maven release plugin do most of the work for you.
For dependencies that really should have a separate lifecyle...because they change infrequently or are shared by multiple projects, you want to handle those differently. They way I do it is to keep the dependencies at the last release version until a change actually requires an upgrade to the next snapshot. In this way when you go to release the product, you will find all the things that may also be released simply by following the snapshot trails.
I find it also helpful to keep the external dependency versions specified as properties in the top pom of my project. This makes it easy to see at a glance what needs to be released. Look for an example of the Nexus pom.
This is something I find very difficult with maven and internal projects; you have two version control systems (maven's, which, quite frankly, isn't very good) and your source code control's (which, assuming it's CVS or better, supports real workflow).
Here's how we do it:
report --depends on--> core
web --depends on--> core
We use the maven release plug:
report's pom, during development, would have a SNAPSHOT version matching what's in core's pom. I do a mvn clean install in core, then I can see those changes in report in my local environment.
When I do a release of report, I must first release core via the maven release plug. When I I use it on core, it asks me to set the version of core to release (i.e. remove the -SNAPSHOT), to which I say yes, and the resulting released artifact doesn't depend on a SNAPSHOT release. When the release plugin is done, the report pom now depends on the next SNAPSHOT release of core (though you can override this during mvn release:prepare if you want).
The devs on web then get an email that a new version of core is available and they can choose to use it if they wish. Our policy is that they should update before releasing.
This is really the same problem as someone needing to branch code they are working on. You need some form of identifier to be able to get at the specific version until you merge back to the mainline development of that component.
The dependency classifier may be something worth looking into. You'll still need to have developers that will properly identify their modified code.
we work with a "Super Parent".pom-project, in it the versions are defined as properties and in every child.project, the versions are set with those properties
in addition the real projects have no version set, instead they inherit it from their parent pom-project (incl. groupId etc.)
with this set up the versions are only defined in some parent pom-projects, thus the needed setup is minimized
e.g. this structure
super parent pom-project (all 3rd party versions as properties defined, e.g. 2.5.6 spring-framework)
---- persistence-parent pom-project, inherits all from super parent
------ persistence-foobar jar project, inherits all from persistence-parent
---- util-parent
etc.
only versions you see are the ones inside the parent relations
example:
<modelVersion>4.0.0</modelVersion>
<artifactId>foo-bar-foo</artifactId>
<packaging>jar</packaging>
<name>whatever</name>
<description>...</description>
<parent>
<groupId>org.foo.bar</groupId>
<artifactId>persistence-parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>foo-bar</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>foo-bar</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.jdbc</artifactId>
<version>${parent.spring.version}</version>
</dependency>
it works this way, because inside the pom you can use already defined values like version, even if the version is set via inheritance
we combine this with module setups inside the parent projects to make the builds easier