Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using native dependencies inside Maven

A POM dependency contains native libraries (DLLs inside a JAR file). How do I programmatically look up the path of the downloaded JAR file so I can pass it into "java.library.path"?

like image 572
Gili Avatar asked Dec 06 '22 02:12

Gili


2 Answers

Answering my own question: http://web.archive.org/web/20120308042202/http://www.buildanddeploy.com/node/17

In short, you can use the maven-dependency-plugin:unpack goal to extract the libraries into a known path, and pass that into java.library.path:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-dependency-plugin</artifactId>
  <executions>
    <execution>
      <id>unpack</id>
      <phase>compile</phase>
      <goals>
        <goal>unpack</goal>
      </goals>
      <configuration>
        <artifactItems>
          <artifactItem>
            <groupId>org.jdesktop</groupId>
            <artifactId>jdic-native</artifactId>
            <version>${jdic.version}</version>
            <classifier>${build.type}</classifier>
            <type>jar</type>
            <overWrite>true</overWrite>
            <outputDirectory>${project.build.directory}/lib</outputDirectory>
          </artifactItem>
        </artifactItems>
      </configuration>
    </execution>
  </executions>
</plugin>
like image 60
Gili Avatar answered Dec 29 '22 22:12

Gili


Since System.load() can't load libraries from within a jar, you will have to use a custom loader which extracts the library to a temporary file at runtime. Projects With JNI discusses this approach and provide code for the custom loader.

Library loader

We now have our JNI library on the class path, so we need a way of loading it. I created a separate project which would extract JNI libraries from the class path, then load them. Find it at http://opensource.mxtelecom.com/maven/repo/com/wapmx/native/mx-native-loader/1.2/. This is added as a dependency to the pom, obviously.

To use it, call com.wapmx.nativeutils.jniloader.NativeLoader.loadLibrary(libname). More information is in the javadoc for NativeLoader.

I generally prefer to wrap such things in a try/catch block, as follows:

public class Sqrt {
    static {
        try {
            NativeLoader.loadLibrary("sqrt");
        } catch (Throwable e) {
            e.printStackTrace();
            System.exit(1);
        }
    }
    /* ... class body ... */
}

An alternative would be to unpack the dependency, for example using dependency:unpack.

like image 21
Pascal Thivent Avatar answered Dec 29 '22 21:12

Pascal Thivent