How to configure maven or eclipse in order to use the RELEASE constant within versions? - eclipse

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.

Related

Get Jenkins plugin dependencies auto installed

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.

maven: automatic upgrade version in all dependent projects

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.

Can someone explain Maven 2 (or 3) dependency resolution to me?

I used Maven before in quite a few projects but they we already configured by someone else. I quickly understood the main concepts (groups, artifacts and versions for jars, local and remote repositories) so I assumed that if I'm asked I'll be able to set up a new project from scratch easily.
That turned out not to be the case when I deal with multiple modules which depend on one another. I poked around maven docs but they are either way too concise or way too technical (sometimes I get a feeling that Maven people wrote it for themselves and not for Maven users). So I'm asking for community help.
Here's a typical scenario:
Three repositories:
My local repo at <User>/.m2
My company repo at http://maven.mycompany.com/repository
Maven Central at http://repo1.maven.org/maven2/
I'm building a normal Java EE project consisting of one EJB jar with a corresponding client jar, a web module and a JPA module (I like keeping my entities and all db-connectivity separated from business logic). That gives me 5 project in my IDE:
myapp-ear
myapp-ejb
myapp-ejb-client
myapp-jpa
myapp-web
myapp-jpa is used by myapp-ejb and myapp-web. myapp-ejb-client contains business interfaces for my EJBs.
How should I set all that up? I suspect that I need some kind of parent project but I'm not sure how should I organize inter-project dependency resolution. For example: currently when I specify
<dependency>
<groupId>com.mycompany.myapp</groupId>
<artifactId>myapp-jpa</artifactId>
<version>0.1-SNAPSHOT</version>
</dependency>
in myapp-ejb's pom.xml maven tries to search for it in my repository and tells me that the .jar can't be found. Even if I build and install all app components into my local repository one by one Maven always fails to build the ear file itself :(
I'd love to get it working under Eclipse or NetBeans.
I think you're on the right path. You need a parent project to pull it all together. In the parent project (and here is the important part) you need your dependencies laid out NOT in the dependency section of your parent pom, rather, you need them in your dependencyManagement section. Then, in your child pom's you can declare dependencies that are in the parent.
The only other gotcha (that I can think of) is that when you check the project using a version control system in Eclipse you need to remember to check the parent project out "as Maven project" otherwise the m2Eclipse plugin tends to freak out and not resolve things properly.
I hope this helps.

How to deal with Maven projects containing several internal artifacts?

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.

Maven 2 project versions, dependency versions, and perpetual releasing

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