maven-jar-plugin and transitive dependencies - maven-2

I'm using both the assembly and jar plugins to deploy my application. I'm also using the jar plugin to help me generate the classpath in the manifest file using
<addClasspath>true</addClasspath>
While that seems to work, the problem comes when I try executing the jar (it has a proper main class specified) - it will fail to locate a library that's actually a transitive dependency. So my project A depends on project B, and project B depends on jar C. The assembly plugin will correctly zip up A, B, and C, but the jar plugin did not include C in the manifest, causing a ClassNotFoundException.
I don't see any options in maven-jar-plugin that lets me specify that transitive dependencies are required.
Am I doing it the right way? Anyone else managed to get transitive dependencies generated into the manifest? Maybe I'm doing something wrongly or out of order. Any help appreciated.

i tried to solve the mentioned problem. in my case it worked (maven-jar-plugin v2.2).
i've got a parent project called jarloading that has 3 childs:
main: with dependency to a
a: with dependency to b
b: with dependency to a
after calling
mvn package
publishing it using a deploy script containing
rm -r ~/Desktop/jarloading-bin
mkdir ~/Desktop/jarloading-bin
cp a/target/a-0.0.1-SNAPSHOT.jar ~/Desktop/jarloading-bin/
cp b/target/b-0.0.1-SNAPSHOT.jar ~/Desktop/jarloading-bin/
cp main/target/main-0.0.1-SNAPSHOT.jar ~/Desktop/jarloading-bin/
changing to directory
cd ~/Desktop/jarloading-bin
and running
java -jar main-0.0.1-SNAPSHOT.jar
it worked fine.
but actually the point is, how the classpath is listed in manifest file:
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: rschmid
Build-Jdk: 1.6.0_07
Main-Class: Main
Class-Path: a-0.0.1-SNAPSHOT.jar b-0.0.1-SNAPSHOT.jar
pom.xml of main project:
...
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<index>true</index>
<manifest>
<mainClass>Main</mainClass>
<addClasspath>true</addClasspath>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>ch.fiftynine.lab</groupId>
<artifactId>a</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
...
pom.xml of a project:
...
<dependencies>
<dependency>
<groupId>ch.fiftynine.lab</groupId>
<artifactId>b</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
...
pom.xml of b project contains nothing really special.
and attached source code and binaries:
source code
binaries

I couldn't get the maven-jar-plugin to work, I had to use the maven-assembly-plugin.
Examples:
Brian Fox's Blog (this is the one I followed)
Maven Assembly Plugin Usage Guide
similar example by Scott Leberknight

I kinda managed to resolve by... not actually resolving it. I checked closer and still don't know why some transitive dependencies aren't getting picked up - it seems to skip of them and they end up not getting generated into the MANIFEST.
I dug around a bit and played with the maven-dependency-plugin. Surprisingly, configuring <attach>true</attach> and tying it to the assembly:assembly phase solved the classpath issue.

Related

building maven flex project with flex mojo depending on apache sdk fail

I have a mavenized flex project wich builds fine with adobe sdke 4.6.
Now , i'm trying to compile it with apache recent sdk .
I mavenized the sdk and copied the dependencies in local repo .
the apache version that i mavenized is : 4.13.0.20140701 .
my pom is as below :
<properties>
<flexmojos.version>7.0.1</flexmojos.version>
<flex.version>4.13.0.20140701</flex.version>
<flash.version>11.1</flash.version>
</properties>
<build>
<sourceDirectory>src/main/flex</sourceDirectory>
<plugins>
<plugin>
<groupId>net.flexmojos.oss</groupId>
<artifactId>flexmojos-maven-plugin</artifactId>
<version>${flexmojos.version}</version>
<extensions>true</extensions>
<configuration>
<debug>true</debug>
<sourceFile>ComptaFlex.mxml</sourceFile>
<services>${basedir}/src/main/flex/services/services-config.xml</services>
<compilerWarnings>
<warn-no-constructor>false</warn-no-constructor>
</compilerWarnings>
</configuration>
<dependencies>
<!-- This handles a bug in maven which causes problems with flex resources -->
<dependency>
<groupId>net.flexmojos.oss</groupId>
<artifactId>flexmojos-threadlocaltoolkit-wrapper</artifactId>
<version>${flexmojos.version}</version>
</dependency>
<!-- Without this FM will use the compiler configured in its master
pom, which will result in version conflicts -->
<dependency>
<groupId>org.apache.flex</groupId>
<artifactId>compiler</artifactId>
<version>4.13.0.20140701</version>
<type>pom</type>
</dependency>
</dependencies>
</plugin>
<plugin>
I got maven compile error as :
xmojos.oss:flexmojos-flex-compiler:jar:7.0.1 -> net.flexmojos.oss:flexmojos-generator-internal-compiler-iface:jar:7.0.1 -> org.apache.flex:compiler:pom:4.12.1.20140427: Failed to read artifact descriptor for org.apache.flex:compiler:pom:4.12.1.20140427: Could not transfer artifact org.apache.
it seems that flex mojo always use a default apache version and ignores mine provided . how could i force flexmojo build with my given version .
Flexmojos-maven-plugin version 7.0.x is built using FDK 4.12.1.20140427. This FDK declared as dependency to this maven plugin.
You need firstly mavenize FDK 4.12.1.20140427 and put it to you maven repository. Only after that you can mavenize other versions of FDK.
A dirty work around is to change flexmojo-parent pom file : and edit by hand :
<flex.version>4.13.0.20140701</flex.version>
until flexmojo developpers comes with a better response .
I have written quite a bit of documentation lately, please check-out at: https://cwiki.apache.org/confluence/display/FLEX/Preparing+FDKs+for+Maven+builds
The short version:
We have created a maven extension that should automatically download and install Flex SDKs as they are referenced in the maven build. Also Flexmojos 7.1.0-SNAPSHOT has been updated to no longer contain a reference to any FDK artifact. Also we now use 3-segment versions such as: 4.14.1

New at Maven: Using the shade plugin and 3rd party jars

This should be pretty simple, but I can't the around to it. I need to create an uberjar using 3rd party jars. I've already followed these instructions: Including a non-Mavenized dependency so it works with maven-shade-plugin and added them to the local repository. But now what? Every Maven tutorial/example is kinda shady (pun intended) and I just don't know how to edit the .pom file properly in order to make it work.
Besides, I'm confused about the shade "plugin" overall. I mean, I followed the basic Maven tutorials and it went all fine and dandy. But when I look into the shade plugin page, I can't find it to download, except for the source code. I mean, isn't it a plugin? Shouldn't I download the binaries and install it into Maven somehow?
Sorry about the extreme noobish question but, needless to say, I know squat about Maven.
To create your shaded (uber) jar, you just need to declare the shade plugin in your pom.xml.
With regards to installation of the shade plugin, simply declaring it in the plugins section of your pom.xml is all you need do. Maven plugins are not installed manually, but are automatically downloaded by Maven (if not already downloaded; just like dependencies), stored in your local repository, and used whenever a project needs them.
As to using it, much like other plugins, declare it in your pom.xml by adding a <plugin> element with your configuration needs. This plugin does nothing automatically (some do, some don't) - you have to specify which "goal" to execute (think "method of a class"), and in which "phase" (think "step" of the build process). Unless you have strange needs, specify the "shade" goal in the "package" phase (see below).
For more configuration possibilities, see the shade usage page, and their examples (especially selecting contents for uber jar). Here is a simple example which, when you run mvn package, replaces your original jar in the target/ directory with the uber jar. It only includes the runtime dependencies, not the ones used at test time (notice the <scope> element of the junit dependency, which is not included in the uber jar).
<project>
<groupId>com.sample</groupId>
<artifactId>test</artifactId>
<version>1.0</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.sample</groupId>
<artifactId>test-core</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
If you have already downloaded the binaries and installed them into your local Maven repository all that remains is to declare them as dependencies in the POM. If the shade plugin is also declared in the POM a simple "mvn install" should generate a standalone JAR in the target directory.

Maven: Including jar not found in public repository

If I was to use a 3rd party library that was not in the maven public repository, what is the best way to include it as dependency for my project so that when someone else checks out my code it will still be able to build?
i.e.
My Application "A" depends on jar "B" which does not exist in the public repository. I, however, wish to add "B" as a dependency to "A" such that when a person on the other side of the world could check out the code and still be able to build "A"
You can install the project yourself.
Or you can use the system scope like the following:
<dependency>
<groupId>org.group.project</groupId>
<artifactId>Project</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>${basedir}/lib/project-1.0.0.jar</systemPath>
</dependency>
systemPath requires the absolute path of the project. To make it easier, if the jar file is within the repository/project, you can use ${basedir} property, which is bound to the root of the project.
If you have a parent project with a module that is in this situation (requires a dependency not in a repository) you can setup your parent project to use the exec-maven-plugin plugin to auto-install your dependent file. For example, I had to do this with the authorize.net jar file since it is not publicly available.
Parent POM:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<inherited>false</inherited>
<executions>
<execution>
<id>install-anet</id>
<phase>validate</phase>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>mvn</executable>
<arguments>
<argument>install:install-file</argument>
<argument>-Dfile=service/lib/anet-java-sdk-1.4.6.jar</argument>
<argument>-DgroupId=net.authorize</argument>
<argument>-DartifactId=anet-java-sdk</argument>
<argument>-Dversion=1.4.6</argument>
<argument>-Dpackaging=jar</argument>
</arguments>
</configuration>
</plugin>
</plugins>
</build>
In the above example, the location of the jar is in the lib folder of the "service" module.
By the time the service module enters the validate phase, the jar will be available in the local repository. Simply reference it in the way you set up the groupid, artifact, etc in the parent pom. For example:
<dependency>
<groupId>net.authorize</groupId>
<artifactId>anet-java-sdk</artifactId>
<version>1.4.6</version>
</dependency>
Using system scope may work but it is not recommended even in the Maven specification.
it is not portable.
from Maven book:
system- The system scope is similar to provided except that you
have to provide an
explicit path to the JAR on the local file system. This is intended to allow compilation
against native objects that may be part of the system libraries. The artifact is assumed
to always be available and is not looked up in a repository. If you declare the scope to
be system, you must also provide the systemPath element. Note that this scope is not
recommended (you should always try to reference dependencies in a public or custom Maven
repository).
The best approach is to install to your local repository or to your enterprise repository to be accessible to all your peers.
this is very easy if you are using a repository manager such as Nexus.
This solution worked for me;
1. Created a local-maven-repo in my project's root directory and copied all my jars in the
2. Executed the following command to generate the necessary pom files and metadata etc for each and every jar that I needed to use;
mvn deploy:deploy-file -DgroupId=<somegroupid> -DartifactId=<someartifact> -Dversion=1.0.0 -Durl=file:./local-maven-repo/ -DrepositoryId=local-maven-repo -DupdateReleaseInfo=true -Dfile=<path to jar file>
This generated a new jar file with a pom file inside the local-maven-repo and I was able to include into my project as a dependency like this;
<dependency>
<groupId>somegroupid</groupId>
<artifactId>someartifact</artifactId>
<version>1.0.0</version>
</dependency>
Then mvn package ensured that my project dependencies are resolved and packaged with my war file.
If you are using groovy/grail tool suite (GGTS) then you can directly import that third party dependency (but be sure you have that third party dependency in your local repository) using below steps :
Go to the Project Explorer and right click on project.
Click on import option.
Expend the maven option and select Install or deploy an
artifact to a maven repository and click next.
Brows and select that third party dependency using Artifact File
option and enter the detail of Group Id, Artifact Id and Version
using POM.xml file and click on finish
Wait some moment and possibly error would have gone for that problem.
Generally speaking, you should first put the 3rd party jar into your local repository. After that you can use it by adding the dependency into pom.xml.
For example.
1.put the jar into your local repository first:
mvn install:install-file -Dfile=<path-to-file>
Note: this command requires maven-install-plugin version 2.5 or later. If not, You can refer to Here
2.use the jar by adding the dependency into you project's pom.xml.
just add this into the pom.xml of your project:
<dependency>
<groupId>${the groupId in the jar's pom.xml}</groupId>
<artifactId>${the artifactId in the jar's pom.xml}</artifactId>
<version>${the version in the jar's pom.xml}</version>
</dependency>
3.you can then package or deploy your project by running mvn package or mvn deploy
The 3rd party jar will also be included in the package.

Untarring maven assembly archive into bundle module

I have several sub module (say A, B + C) that each generate an assembly tar.gz and a module (X) that will bundle them all together by extracting the tarballs into the target directory.
Right now setting up my dependency on A, B + C using the classifier and type in module X POM and using an assembly file with dependencySets the module does not seem to be pulling the tarball from my local repo, rather rebuilding it.
This is causing issues because A, B + C each has it's own filters. When X rebuilds A it leaves it unfiltered. I want maven to just either get the A-distro.tar.gz from my repo or if not present rebuild A, put it in the repo then have X use this.
Here is the assembly.xml file I'm using. I couldn't get moduleSets to work when using the coordinates so went for this:
<assembly>
<id>distro</id>
<formats>
<format>dir</format>
<format>tar.gz</format>
</formats>
<baseDirectory>${project.version}</baseDirectory>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<useTransitiveFiltering>true</useTransitiveFiltering>
<useProjectArtifact>false</useProjectArtifact>
<unpack>false</unpack>
<outputDirectory>/lib</outputDirectory>
<excludes>
<exclude>*:tar.gz</exclude>
</excludes>
</dependencySet>
<dependencySet>
<useTransitiveFiltering>true</useTransitiveFiltering>
<useProjectArtifact>false</useProjectArtifact>
<unpack>true</unpack>
<outputDirectory>/</outputDirectory>
<includes>
<include>*:tar.gz</include>
</includes>
</dependencySet>
</dependencySets>
</assembly>
And POM for project X:
<project>
<parent>
<artifactId>parent_project</artifactId>
<groupId>org.myorg</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.myorg</groupId>
<artifactId>X</artifactId>
<packaging>pom</packaging>
<name>X</name>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.myorg</groupId>
<artifactId>A</artifactId>
<classifier>distro</classifier>
<type>tar.gz</type>
</dependency>
</dependencies>
</project>
(RS moved content from OP's answer)
ok thanks for replying.
I've created a test project using the principle you describe of having one module for assembly, one for aggregator:
./pom.xml
./bundle
./bundle/pom.xml
./bundle/src
./bundle/src/main
./bundle/src/main/assembly
./bundle/src/main/assembly/assembly-files.xml
./bundle/src/main/assembly/assembly.xml
./module1
./module1/pom.xml
./module1/src
./module1/src/main
./module1/src/main/assembly
./module1/src/main/assembly/assembly-files.xml
./module1/src/main/assembly/assembly.xml
./module1/src/main/conf
./module1/src/main/java
./module1/src/main/java/org
./module1/src/main/java/org/test
./module1/src/main/java/org/test/Test.java
./module2
./module2/pom.xml
./module2/src
./module2/src/main
./module2/src/main/java
./module2/src/main/java/org
./module2/src/main/java/org/test
./module2/src/main/java/org/test/Test.java
Module 1 produces an assembly file of the following coordinates:
<dependency>
<groupId>org.test</groupId>
<artifactId>module1</artifactId>
<version>1.0-SNAPSHOT</version>
<classifier>distro</classifier>
<type>tar.gz</type>
</dependency>
The following file is produced:
~/mvnrepos/org/test/module1/1.0-SNAPSHOT/module1-1.0-SNAPSHOT-distro.tar.gz
When building the bundle with the following assembly the tar.gz is pulled in and used:
<assembly>
<id>distro</id>
<formats>
<format>dir</format>
<format>tar.gz</format>
</formats>
<baseDirectory>${project.version}</baseDirectory>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<includes>
<include>org.test:module1:tar.gz</include>
</includes>
<useTransitiveFiltering>true</useTransitiveFiltering>
<useProjectArtifact>false</useProjectArtifact>
<unpack>true</unpack>
<unpackOptions>
<excludes>
<exclude>lib/</exclude>
</excludes>
</unpackOptions>
<outputDirectory>lib/</outputDirectory>
</dependencySet>
</dependencySets>
<!-- just includes conf and bin dirs -->
<componentDescriptors>
<componentDescriptor>src/main/assembly/assembly-files.xml</componentDescriptor>
</componentDescriptors>
</assembly>
However if I cleardown my repository and clean the project at the root so the tar.gz is removed completely, when I change into the bundle dir and mvn install it fails as maven cannot work out it needs to rebuild module 1 in the absence of the tar.gz in order to get it. Here is my bundle pom:
<project>
<parent>
<artifactId>test_parent</artifactId>
<groupId>org.test</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.test</groupId>
<artifactId>bundle</artifactId>
<packaging>pom</packaging>
<name>bundle</name>
<version>1.0-SNAPSHOT</version>
<url>http://maven.apache.org</url>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.test</groupId>
<artifactId>module1</artifactId>
</dependency>
<dependency>
<groupId>org.test</groupId>
<artifactId>module2</artifactId>
</dependency>
<dependency>
<groupId>org.test</groupId>
<artifactId>module1</artifactId>
<version>1.0-SNAPSHOT</version>
<classifier>distro</classifier>
<type>tar.gz</type>
<scope>runtime</scope>
</dependency>
</dependencies>
</project>
How can I get maven to realize that the assembly must be rebuilt by rebuilding module 1?
I'm trying to keep each assembly within a separate module so each module can be built and tested as a separate unit rather than having an aggregator which needs to be rebuilt in order to run any of the modules. Then if the a full run is required the bundle can be built by simply untarring each assembly tarball into a directory under bundle/target.
Perhaps the above is going against the grain - but this seems to be the thrust of the maven assembly chapter in the Sonotype book:
http://www.sonatype.com/books/maven-book/reference/assemblies-sect-assembling-via-depend.html
Unfortunately the examples zip provided by sonotype has nothing under chapter 12 :-(
Of course I could just break out into ant and use this but would like to implement purely in maven if at all possible.
btw maven-assembly-plugin version is 2.2-beta-2.
I'm not sure I understand your problem so let me try to rephrase it.
You have 4 projects, A, B, C and X. You have A, B, and C defined as sub-projects of X
When you build project X you want to include the tar.gz files for projects A, B and C.
The problem is that you want to build A only if required, and download it from the project
repository if it is already present?
Assuming I understand the problem correctly, I'm still not clear how you expect the children to be conditionally built. If X declares the others as modules Maven will always build them along with the parent. If X declares the others as dependencies they will only ever be treated as dependencies, so the build will fail unless the artifacts exist in the repository (i.e. you've already built them).
If you want to be able to exercise flexibility over the build, I'd recommend separating the responsibilities of assembly and aggregator into different projects.
The aggregator simply declares the projects as modules so you can conveniently build all the projects in one command.
The assembly project (your project X) declares dependencies on projects A, B and C. When you build project X it is required that the others have already been built, but if built in the aggregator, the reactor will have built them first. Whereas if you build it standalone, you know the others are up to date.
Some additional points on Maven usage that should clarify this approach.
The Maven repository is a record of all the artifacts you've developed. You don't need to clear the local repository between builds. It is intended to act as a repository of all the artifacts. So if you install project A, that is the version that will always be used (unless and until you rebuild project A).
If you do have to clear the local repository, you should deploy your artifacts to a remote repository (see the relevant section of the Nexus book for guidance on getting started) so they can be incorporated into your build for project X even if the local repository is cleared.
So the workflow for building the projects is:
Run mvn install on the aggregator project or the relevant project (A,B, or C).
Projects are installed to the local repository.
Don't clear the local repository!
Run mvn install on project X, Maven will retrieve the dependencies from the repository and package them into your assembly.
If you use mvn deploy, the same principles apply, but because the artifacts are in the remote repository you have freedom to clear the local repository.
To emphasise my earlier points:
There is no mechanism to conditionally build modules. They either build or they don't (however some steps of the build might be skipped if they are not needed, e.g. compilation might have already been done in a previous build)
There is no need to purge the local repository (and if you do, you should have the modules deployed to a remote repository so they can be retrieved).
ok I should have been more clear on why I was clearing down the local repo - I understand this is not a normal step as part of the build cycle.
I was clearing down my local repo to emulate what would happen if I tried a build for the very first time and nothing exists on a remote repo. This is because on checking out the parent + modules all the code I need is present.
Parent
\----module1 (includes assembly classifier)
|
\----module2
|
\----bundle
eg build with empty repo from parentbuilds module1, module2 then bundle. All works well in this order:
parent, module1, module2, bundle
however if I have an empty repos and cd to X then build maven cannot work out that it needs to build the parent which depends on module1 and module2, so if possible I'd like it to build in this order:
parent, module1, module2, bundle
I think this is not possible in maven as you say there is no mechanism for conditional module builds! I thought maven would support this as it has info on the parent and the parent has info on the children, but I think I was inferring too much.
Many thanks for your replies Rich. Getting there with maven but it is like pulling teeth, in large part due to the style of the sonotype manual.
ps editing of questions looses context. I didn't realise stackoverflow did this. usenet style had it right first time, write your own reply, include references to former replies if required, post at the bottom. Editing prior posts IMHO erases the flow of a conversation - for some issues the journey to the solution is as instructive as the destination! this last paragraph is 400 chars :-)
eg I could not put this comment in as recommended because it goes over the technical sound barrier of 600 characters.

Maven classpath order issues

Does anyone know of a way to set a specific classpath order in Maven2, rather than the random ordering I appear to experience at the moment?
There are a number of legitimate reasons for wanting to do this:
A vendor has supplied a patch jar, which contains overriding classes for a previously released jar and therefore the patch jar must appear first in the classpath ordering.
Two jar's found on the classpath discovered by traversing pom dependencies contain the same class in the same package with different signitures. For example:
jboss
jbossall-client
4.2.0.GA
org.hibernate
hibernate
3.1
both contain:
org.hibernate.util.ReflectHelper.class, but the jbossall-client version is missing the getFastClass method.
From googling I see that this is perhaps a point of contention between maven enthusiasts and people facing this particular issue, but surely there are legitimate reasons for classpath ordering.
Any advice from anyone that has solved this particular quandary would be much appreciated!
Thanks
As of version 2.0.9 maven uses pom order for classpath, so you can actually manipulate it now. We mostly supress transitive dependencies to external libraries that we also include directly.
From the release notes of maven 2.0.9:
MNG-1412 / MNG-3111 introduced deterministic ordering of dependencies on the classpath. In the past, natural set ordering was used and this lead to odd results. The ordering is now preserved from your pom, with dependencies added by inheritence added last. In builds that had conflicting or duplicate dependencies, this may introduce a change to the output. In short, if you have weird issues with 2.0.9, take a look at the dependencies to see if you have conflicts somewhere.
Maven 2.0.9 adds correct ordering so you absolutely must have that version or higher for the below to work.
Secondly you need the an updated plugin. The Maven guys are working on a fix, its in their jira to fix but this is something I urgently needed. So in the meantime I have fixed this myself and you can pull the Modified plugin source code from github.
Edit: Refer to http://jira.codehaus.org/browse/MECLIPSE-388
There are two ways to install it, either pull my modified code and install it or download the prebuilt jar and just add it.
Building the plugin
Run maven install from the plugin directory you checked out and then add the following in your plugins section of your projects pom:
<build>
</plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.8-cpfix</version>
</plugin>
</plugins>
</build>
Download the jar
Alternatively if you don't want to download and compile yourself then you can just get hold of the jar file and install it yourself.
Once you have the file run
mvn install:install-file -Dfile=<path-to-file> -DgroupId=org.apache.maven.plugins \
-DartifactId=maven-eclipse-plugin -Dversion=2.8-cpfix -Dpackaging=jar
Regardless of how you installed it now when you run mvn eclipse:eclipse it will pick up the modified code and order the dependencies based on the order you defined in your pom file, no alphabetical ordering. It will also put the JRE container at the top of the dependencies.
Hopefully the real version of this code will come out soon, but in the meantime this fix has worked for me on my project and I hope it can help some others as well.
Rather a further qualification of the question than an answer:
under "Maven Dependencies" Eclipse does not seem to honour the POM-order.
(it does use the POM-order under "Java Build Path" & in the Classpath)
Is that the expected behaviour?
I'm using Eclipse 2021-09 (which has Maven 3.8.1 embedded) under Windows 10.
Here's the POM:
<project
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.group</groupId>
<artifactId>arty.fact</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Maven Dependency Order</name>
<properties>
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.source>17</maven.compiler.source>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>wsdl4j</groupId>
<artifactId>wsdl4j</artifactId>
<version>1.6.3</version>
<exclusions><exclusion><groupId>*</groupId><artifactId>*</artifactId></exclusion></exclusions>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.14.1</version>
<exclusions><exclusion><groupId>*</groupId><artifactId>*</artifactId></exclusion></exclusions>
</dependency>
</dependencies>
</project>
The Maven Dependencies looks like this:
If you have problem starting with IntelliJ IDEA, you can change the dependencies order from project structrue.