简体   繁体   中英

Adding a JNI library to the local Maven Repository

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.

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")

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

As an alternative to unpacking your libraries at runtime, you could store them as jars in Maven but unpack them at build time: http://www.buildanddeploy.com/node/17 .

The maven-nativedependencies-plugin plugin will do this for you automatically, as long as you follow their naming convention.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM