6

I'm currently in the midst of converting a large multi-module project (~100 sub-modules) to use Maven. Currently we use Ant + Ivy.

So far no major issues have cropped up and I'm comfortable that Maven is still a good fit. However, I wonder if there is a better way to handle native dependencies.

So far I have come to the following conclusions.

  1. It's best to install each native dependency into the maven repo either as a standalone library or an archived package containing multiple dependencies.
  2. Rather than get lost in declaring each and every dependency with the Maven dependency plugin, I opted to give each a classifier (e.g. natives-win32) and use the following in the parent POM:

            <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>2.4</version>
            <executions>
                <execution>
                    <id>copy</id>
                    <phase>compile</phase>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                    <configuration>
                        <includeScope>runtime</includeScope>
                        <includeClassifiers>natives-win32</includeClassifiers>
                        <outputDirectory>${project.build.directory}/natives</outputDirectory>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    

So far this seems to be a simple all-round solution that doesn't require too much messing about to add new native dependencies. It also offers me a simple all-round solution for managing natives. The only thing I must do is ensure that my /natives/ directory is defined on java.library.path.

One thing that bothers me (a little) about this approach is that all my native dependencies get copied around to each sub-module that expresses a transitive dependency on them, whilst my happy jar libraries are added to the classpath referenced to where they sit in my local repository (no copy required).

Is there no way to be smarter about this and have my natives referenced from withing their repository location (assuming I don't have them archived, i.e. dll). That would save a bunch of unnecessary copying about.

Are there any other potential gotchas' that I should be concerned about with the above approach?

S73417H
  • 2,661
  • 3
  • 23
  • 37
  • How did you solve that via Ivy ? The way you described that? – khmarbaise Apr 09 '12 at 17:02
  • It seems to be solved quite poorly with our Ivy configurations. Firstly, debug/run configurations for eclipse setup the runtime dependencies by referencing each individual one in a shared repository which is a mapped directory on each developers machine. When deployed or tested, ant scripts take over and move the dependencies as needed. It's quite a mess. – S73417H Apr 10 '12 at 00:55
  • Hmmm, I like your solution. Seems what you really want is an additional goal to the dependencies plugin that sets a property to be the path list of resolved dependencies. That would be the final piece in the puzzle. Should be easy, why not take a stab at a patch? Ping me if you are successful in writing such a patch and I will take a look at applying it. – Stephen Connolly Aug 15 '12 at 06:22
  • Stephen. In the end I opted to use the [maven natives plugin](http://code.google.com/p/mavennatives/). The reason being was that it includes an eclipse plugin that seamlessly sets up the developers environment to include the native dependencies. I just bare the consequence of having multiple libs copied around because at the end of the day most natives exist in bundles anyway which are zipped up and subsequently must be unpacked. Maybe in the future a maven plugin could be implemented which at the very least unpacks them to a natives "staging" area for repeated use. Cheers. – S73417H Oct 08 '12 at 13:42

3 Answers3

0

Your snippet shows a goal attached to a build phase, not a dependency. Is the 'copy dependencies' goal in a super pom and inherited by all modules? There's no way to move it only to the modules which are going to be run/packaged as an app?

ianpojman
  • 1,743
  • 1
  • 15
  • 20
0

It could be, that I didn't got it. But why don't you deploy all your native libs into the repository at first. If the native libs are stable and change seldom, That could be done in a seperate reactor.

And afterwards you reference those native dependencies simply via GAV as any other dependency. Also the problem af unnecessary copying is solved by that.

vach
  • 1,825
  • 1
  • 11
  • 8
0

I ended up using the maven natives plugin and dealing with the fact that I have redundant copies of the native libraries around the place. The reason for this was primarily due to the simplicity that the plugin offers and the fact that it also has a related eclipse plugin that sets up natives in developers eclipse environment without intervention.

S73417H
  • 2,661
  • 3
  • 23
  • 37
  • For the record, I've forked the mavennatives plugin and improved upon it. It offers the same features plus some speed improvements by not downloadingnatives dependencies not related to your platform and much more. Find nativedependencies-maven-plugin here if interested: https://github.com/fmarot/nativedependencies-maven – Francois Marot Mar 26 '16 at 10:02