During Java development, we sometimes come into contact with many local libraries, so when packaging the project, we have to face a choice: either put the library file together with the wrapped jar file; or wrap the library file into the jar.
There are many release advantages to wrapping a small project into a jar. This time, we will share a method to include JNI into a jar.
[Implementation idea]
After packaged JNI libraries (dll, so, etc.) into jars, we cannot access them through paths, and the library's reading depends on an external library file with the corresponding name under java.library.path. We only need to release it from the jar package before calling JNI, which is similar to the file copying process.
[Selecting deployment location]
java.library.path is not a fixed location, and you can print it using the following code:
System.out.println(System.getProperty("java.library.path"));
For example, on my computer, the result is:
D:/Program Files (x86)/Java/jre7/bin;C:/windows/Sun/Java/bin;C:/windows/system32;C:/windows;D:/Program Files (x86)/Java/jre7/bin/client;D:/Program Files (x86)/Java/jre7/bin;D:/Program Files (x86)/Java/jre7/lib/i386;C:/Program Files (x86)/NVIDIA Corporation/PhysX/Common;C:/windows/system32;C:/windows;C:/windows/System32/Wbem;C:/windows/System32/WindowsPowerShell/v1.0/;E:/Develop/jdk1.7.0_71/bin;E:/Develop/Git/cmd;E:/Develop/Git/bin;E:/Develop/apache-maven-3.2.1/bin;E:/eclipse-java-luna-SR1-win32/eclipse;;.
The absolute path will change due to different systems, so here we choose the relative path ".", which is in the project directory.
[JNI deployment class]
import java.io.File;import java.io.FileOutputStream;import java.io.InputStream;import java.util.Arrays;import java.util.LinkedList;import java.util.List;import java.util.List;public class JNIDevelopment {byte[] cache;List<String> sources;public JNIDevelopment(){cache = new byte[1024];sources = new LinkedList<String>();//Add the local library file name here, you can also slightly modify and read an external xml or properties sources.add("luajava-1.1.dll");sources.add("libluajava-1.1.so");}private Boolean sourceExist(String sourceName){File f = new File("." + File.separator + sourceName);return f.exists();}public void doDefaultDevelopment(){for (String s:sources){doDevelopment(s);}}public Boolean doDevelopment(String sourceName){if(sourceExist(sourceName)){return true;} else{try{File f = new File("." + File.separator + sourceName);if(!f.exists()){f.createNewFile();System.out.println("[JNIDEV]:DEFAULT JNI INITION:"+sourceName);}FileOutputStream os = new FileOutputStream(f);InputStream is = getClass().getResourceAsStream(sourceName);if(is == null){os.close();return false;}Arrays.fill(cache,(byte)0);int realRead = is.read(cache); while(realRead != -1){os.write(cache, 0, realRead);realRead = is.read(cache);}os.close();}catch(Exception e){System.out.println("[JNIDEV]:ERROR IN COPY JNI LIB!");e.printStackTrace();return false;}}return true;}public static void main(String[] args) {JNIDevelopment deve = new JNIDevelopment();deve.doDefaultDevelopment();try{System.loadLibrary("luajava-1.1");System.out.println("Local library loading successfully");}catch(UnsatisfiedLinkError e){System.out.println("Local library loading failed");}}}Then we place the local library under the same package as this class:
[Run result]
[JNIDEV]:DEFAULT JNI INITION:luajava-1.1.dll
[JNIDEV]:DEFAULT JNI INITION:libluajava-1.1.so
Local library loading successfully
Summarize
The above is all about the brief discussion on packaging the JNI library into a jar file. I hope it will be helpful to everyone. Interested friends can refer to other Java-related topics on this site. If there are any shortcomings, please leave a message to point it out. Thank you friends for your support for this site!