Some things that you might want to know about Maven Tools 4 Eclipse:
How Are Eclipse Bundle Names Converted To Maven Artifact Coordinates?
There are many ways to convert Eclipse bundle names (say org.eclipse.core.runtime 3.7.0.v20110110) to Maven artifact coordinates (groupId:artifactId:version).
For MT4E, this rule was chosen:
- The first three words in the bundle name become the group ID: org.eclipse.core
- The whole bundle name becomes the artifact ID: org.eclipse.core.runtime
- The version is truncated to three numbers: 3.7.0
Reasoning: The third word in the bundle name is the project. This is a good way to group artifacts by project.
The whole name is repeated because there are 27 bundles that end in "runtime" in my 3.7.1/Helios install. That would mean for web projects: Several runtime-3.7.0.jar in the WEB-INF/lib folder and a) no easy way to tell them apart and b) errors during the build. Things would be similar for non-web projects. Yes, it's redundant but it was the most simple way to avoid a whole load of trouble.
Truncating the version was one thing that feels unsafe. The reasons for truncating are:
- Odd qualifiers like R36x_v20101208-1400 or huge cartographic checksums.
- The qualifier has often the same meaning as Maven's SNAPSHOT except for one specific which becomes the release.
- Only very few people are able to tell whether v20100824-2220 or v20100507-1815 is the release version. For almost anyone, the qualifier is just confusing and holds little value.
- The official Eclipse version numbers are 3 integers plus a qualifier. The qualifier is not important when different versions of a bundle are considered.
- Each release must change the version number (the part without qualifier)
- Requiring the qualifier would mean that it becomes impossible to write POM files without external tools or cut&paste of version numbers from a web page.
See also: Version Numbering
Why Are Orbit Bundles Not Mapped To Their Maven Central Coordinates?
If you look at the bundle org.apache.commons.logging_1.1.1.v201101211721, then it seems like it could be mapped to commons-logging:commons-logging:1.1.1 instead of org.apache.commons:org.apache.commons.logging:1.1.1
But the Orbit bundle isn't identical to the Maven artifact:
- The Orbit bundle is signed.
- The Orbit bundle is missing a couple of things (like the folder META-INF/maven/), other files (like META-INF/LICENSE) are moved to a different place.
- The bundle has a new file plugin.properties
If the bundles were mapped to the same coordinate and you started a build on a clean machine (no local repository, yet) with Maven Central and maven.eclipse.org as repositories in your POM, which bundle would you get?
Worse, some Orbit bundles are stripped down versions of Maven artifacts. That means that classes are missing which exist in the original artifact. Or artifacts have been split into several bundles.
A really ugly case is org.apache.batik.pdf which contains classes from commons-logging and commons-io (See bug 350792)! In this case, I can't even use the original Orbit bundle but I have to add additional dependencies to the generated POM and modify the signed JAR or your build will start to break in unpredictable ways when you use BIRT.
Why Are There Profiles In My POM?
Some POMs contain the profiles m4e.orbit (default) and m4e.maven-central. These profiles wrap dependencies so you can select whether you want to stay in the safe Eclipse ecosystem or pull dependencies from Maven Central (see also "Why Are Orbit Bundles Not Mapped To Their Maven Central Coordinates?").
Here are a couple of reasons which you can use to decide which profile you want:
- Do you need to be sure that your code is legally safe to use under the EPL? Stay with m4e.orbit
- If you feel unsure when you include dependencies that were not used to compile all the code in your project → Stay with m4e.orbit
- Do you have a dependency which needs something that exists in Orbit and Maven Central? You might have to switch to m4e.maven-central
Point #2 refers to the fact that all code from the Eclipse foundation is always only compiled against other Eclipse code. So if you use a bundle X that uses org.apache.commons.logging and replace that dependency with the equivalent commons-logging:commons-logging, then things might break because X was compiled against the Orbit bundle but at runtime, the Maven artifact is on the classpath.
Should usually not be a problem; if you find something that doesn't work this way, then please file a bug.
Point #3 refers to projects that need some framework which depends on, say, log4j. log4j can be consumed from Central and Orbit. Of course, the framework you need takes it from Central (because the framework has no idea Eclipse exists) while some dependency from the Eclipse ecosystem might need log4j, too - and pulls that from Orbit.
So all of a sudden, you would end up with log4j twice on the classpath.
How can you solve that? There are several solutions:
- You can add an exclusion for the Eclipse dependency to exclude the version of log4j from Orbit
- You can add an exclusion for the framework dependency to exclude the version of log4j from Maven Central
- You can activate the profile m4e.maven-central - but that will replace all Orbit dependencies with ones from Central. It's a simple solution but it might cause other troubles.
If everything else fails, the profiles give you a handy list to see which Orbit bundle maps to which Maven artifact in a place where you'll likely find it when you need it.