Fork me on GitHub

Usage

The following fragments can be used to execute the NAR plugin to compile and link native code.

Create a Shared Library (but not a JNI library).

<project>
  ...
  <packaging>nar</packaging>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>com.github.maven-nar</groupId>
        <artifactId>nar-maven-plugin</artifactId>
        <version>3.4.1-SNAPSHOT</version>
        <extensions>true</extensions>
      </plugin>
    </plugins>
  </build>
</project>

Create a JNI Library

<project>
  ...
  <packaging>nar</packaging>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>com.github.maven-nar</groupId>
        <artifactId>nar-maven-plugin</artifactId>
        <version>3.4.1-SNAPSHOT</version>
        <extensions>true</extensions>
        <configuration>
          <libraries>
            <library>
              <type>jni</type>
              <narSystemPackage>com.mycompany.mypackage</narSystemPackage>
            </library>
          </libraries>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

Create a JNI Library without linking to C++

It is possible to write your JNI code in C++, use the C++ compiler to compile it and then link it only with the C library (as long as you have not used any C++ library calls). Note the two tags to disable exceptions and not link with C++.

<project>
  ...
  <packaging>nar</packaging>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>com.github.maven-nar</groupId>
        <artifactId>nar-maven-plugin</artifactId>
        <version>3.4.1-SNAPSHOT</version>
        <extensions>true</extensions>
        <configuration>
          <cpp>
            <exceptions>false</exceptions>
          </cpp>
          <libraries>
            <library>
              <type>jni</type>
              <linkCPP>false</linkCPP>
            </library>
          </libraries>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

Create a JNI Library using SWIG generated code

Since SWIG already generated the .h file normally generated by javah, we exclude this file from javah. We also include the compilation and linking with java. The example also shows how to configure the maven-swig-plugin.

<project>
  ...
  <packaging>nar</packaging>
  ...
  <build>
    <plugins>
      <plugin>
        <artifactId>maven-swig-plugin</artifactId>
        <executions>
          <execution>
            <id>swig</id>
            <goals>
              <goal>generate</goal>
            </goals>
            <configuration>
              <cpp>true</cpp>
              <narSystemPackage>org.domain.packagename</narSystemPackage>
              <source>Module.swg</source>
            </configuration>
          </execution>
        </executions>
      </plugin>
      ...
      <plugin>
        <groupId>com.github.maven-nar</groupId>
        <artifactId>nar-maven-plugin</artifactId>
        <version>3.4.1-SNAPSHOT</version>
        <extensions>true</extensions>
        <!-- STRICTLY NO CONFIGURATION, maven-swig-plugin will configure -->
      </plugin>    
    </plugins>
  </build>
</project>

Create a JNI library that is automatically unpacked from the .nar file using the native-lib-loader project

The below example shows how to use native-lib-loader in the NAR plugin. When narSystemPackage detects native-lib-loader in dependencies, narSystemPackage provides the native-lib-loader interface to load the native libraries.

<project>
  ...
  <packaging>nar</packaging>
  ...
  <dependencies>
    <dependency>
      <groupId>org.scijava</groupId>
      <artifactId>native-lib-loader</artifactId>
      <version>2.0.2</version>
    </dependency>
  </dependencies>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>com.github.maven-nar</groupId>
        <artifactId>nar-maven-plugin</artifactId>
        <version>3.4.1-SNAPSHOT</version>
        <extensions>true</extensions>
        <configuration>
          <cpp>
            <exceptions>false</exceptions>
          </cpp>
          <libraries>
            <library>
              <type>jni</type>
<!--
  When generating the NarSystem class, the NAR plugin detects the presence of
  the native-lib-loader dependency and makes full use of it to unpack and load the
  native library.
-->
              <narSystemPackage>com.mycompany.mypackage</narSystemPackage>
              <linkCPP>false</linkCPP>
            </library>
          </libraries>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

Assemble libraries made on different platforms for distribution

This example shows how to download, unpack and assemble the already deployed machine dependent libraries. It also shows the setup of the standard maven-assembly-plugin to pick up the unpacked libraries.

Note there is no "nar" packaging as the normal packaging for assemblies would be "pom".

This example assumes that the dependencies are jni libraries. In other cases the classifiers must be adapted accordingly.

<project>
  ...
  <packaging>pom</packaging>
  ...
  <build>
    <plugins>
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <!--  NOTE 2.1 fails -->
        <version>2.0.1</version>
        <configuration>
          <descriptors>
                        ...
            <descriptor>src/main/assembly/x86-Windows-msvc.xml</descriptor>
            <descriptor>src/main/assembly/ppc-MacOSX-g++.xml</descriptor>
            <descriptor>src/main/assembly/i386-Linux-g++.xml</descriptor>
          </descriptors>
        </configuration>
      </plugin>
          ...    
      <plugin>
        <groupId>com.github.maven-nar</groupId>
        <artifactId>nar-maven-plugin</artifactId>
        <version>3.4.1-SNAPSHOT</version>
        <configuration>
          <classifiers>
            <classifier>x86-Windows-msvc-jni</classifier>
            <classifier>ppc-MacOSX-g++-jni</classifier>
            <classifier>i386-Linux-g++-jni</classifier>
          </classifiers>
        </configuration>
        <executions>
          <execution>
            <goals>
              <goal>nar-download</goal>
              <goal>nar-unpack</goal>
              <goal>nar-assembly</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

The i386-Linux-g++ assembly descriptor is below:

<assembly>
  <id>i386-Linux-g++</id>
  <formats>
    <format>tar.gz</format>
  </formats>
  <fileSets>
    <fileSet>
      <directory>target/nar/lib/i386-Linux-g++/jni</directory>
      <outputDirectory>lib/i386-Linux-g++</outputDirectory>      
      <includes>
        <include>*</include>
      </includes>
    </fileSet>
  </fileSets>
</assembly>