Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

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:

  • Installing these in my local repository, having the .jar depending on the .so library.
  • 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")
                    Is it possible to add the .so with the platform specific classifier with the normal mvn install command?
    – jbx
                    Apr 12, 2012 at 20:33
                    @jbx Maybe you mean mvn deploy? I used it only for java deps built by maven itself. Our JNI deps are built without maven, and loaded to maven repository with cURL by simple bash script.
    – alexkasko
                    Apr 12, 2012 at 20:41
                    No I meant mvn install. I usually do this for 3rd party libraries which are not in the maven repository. maven.apache.org/guides/mini/guide-3rd-party-jars-local.html So essentially what I wish to do is include the .so with the 3rd party jar.
    – jbx
                    Apr 14, 2012 at 17:19
    

    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

    How do you deploy it then and make sure that the native library is put in the right LIBRARY_PATH? – jbx Apr 9, 2012 at 9:48 It doesn't, it loads into a sub directory of java.io.tmpdir and loads it with a full path name. – Peter Lawrey Apr 9, 2012 at 9:50

    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.

    Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.