Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding a JNI library to the local Maven Repository

Tags:

I wish to add a JNI library, including its shared object (.so) file to my project using Maven. Unfortunately it is not yet on a public repository so I guess I have to install it myself on my local repository to have it working.

How do I go about including the native part in Maven to be bundled in my project (and eventually exported with the copy-dependencies plugin). This is a standard J2SE app (not a web-app), with packaging .jar?

The library I am trying to add is junixsocket, just in case it helps to know. It has a .so (native library) component, and the Java .jar component.

I came across maven-nar-plugin which seems to target native builds, but seems to be more oriented towards building a JNI project from code, rather than bundling a 3rd party JNI library, and I can't get to piece the jigsaw puzzle together.

How do I go about:

  1. Installing these in my local repository, having the .jar depending on the .so library.
  2. Including the dependency (on the .jar and .so) in the POM file.

Thanks.

like image 866
jbx Avatar asked Apr 09 '12 09:04

jbx


2 Answers

My approach:

Put .so files to repository with platform specific classifier, like this: sqlite3-3.7.9-linux-x86_64.so. Add .so dependencies for all required platforms:

<dependency>
    <groupId>de.ch-werner</groupId>
    <artifactId>sqlite-jdbc</artifactId>
    <version>3.7.9</version>
    <type>so</type>
    <classifier>linux-x86_64</classifier>
</dependency>

Use this maven assembly plugin config to put all native libs into lib/native directory of you dist:

<dependencySet>
    <outputDirectory>lib/native</outputDirectory>
    <outputFileNameMapping>${artifact.artifactId}${dashClassifier?}.${artifact.extension}</outputFileNameMapping>
    <unpack>false</unpack>
    <useProjectArtifact>false</useProjectArtifact>
    <useStrictFiltering>false</useStrictFiltering>
    <includes>
        <include>*:*:dll:*</include>
        <include>*:*:so:*</include>
        <include>*:*:jnilib:*</include>
    </includes>
</dependencySet>    

Use this class to load libs on app startup (planning to change classifier naming to GNU triplets):

CtzJniUtils.loadJniLibsFromStandardPath(Launcher.class, "sqlite3")
like image 156
alexkasko Avatar answered Oct 19 '22 20:10

alexkasko


I include the .so in the jar and extra the platform specific shared library before loading it. This way it is deployed just like any other jar.

An example of a project where this is done, with multiple .so for different platforms is https://github.com/peter-lawrey/Java-Thread-Affinity

The main class to look at is https://github.com/peter-lawrey/Java-Thread-Affinity/blob/master/src/main/java/com/higherfrequencytrading/affinity/impl/NativeAffinity.java

like image 24
Peter Lawrey Avatar answered Oct 19 '22 19:10

Peter Lawrey