- Articles
- Using native methods from shared libraries in Java/JSP code
- Create Java class containing native method
- Compile Java class nad generate C headers
- Prepare and compile C code of the library
- Call native method from Java (command line)
- Notes
- Java Language Java Native Interface Loading native libraries
- Target file lookup
- Saved searches
- Use saved searches to filter your results more quickly
- License
- scijava/native-lib-loader
- Name already in use
- Sign In Required
- Launching GitHub Desktop
- Launching GitHub Desktop
- Launching Xcode
- Launching Visual Studio Code
- Latest commit
- Git stats
- Files
- README.md
- About
Articles
Using native methods from shared libraries in Java/JSP code
Java hosting clients may want to use some of the vast native methods library pool from inside their Java/JSP code. It may save coding time and also give better performance. Here we give a short example of how to link C and Java code in our Java hosting environment.
Create Java class containing native method
Let’s create a Java class with native method declaration ( NativeMethodLibrary.java ). It accepts single numerical (integer) argument and prints its root. In case of no argument call or parse error default value is used. The code also prints library name expected on your OS (in Linux lib prefix and .so suffix are added). Moving the example from command line Java to JSP will require only changes in the below file so that it becomes valid JSP code.
class NativeMethodLibrary < public native int root (int number); static private String libname = "NativeMethodLibrary"; // load library explicitly static < System.loadLibrary (libname); // absolute path in the below call required // System.load ("/home/username/"+System.mapLibraryName(libname)) >public static void main (String[] args) < int number = 8; if (args.length >0) < try < number = Integer.parseInt(args[0]); >catch (NumberFormatException e) < System.err.println("Argument must be an integer. Using default value of 8"); >> System.out.println("Expected library file name: "+System.mapLibraryName(libname)); NativeMethodLibrary nml = new NativeMethodLibrary (); System.out.println(nml.root (number)); > >
As an alternative to System.loadLibrary you can use System.load . Just comment out first and uncomment the second. Full path to library (a directory) will be required. Library filename part will be autogenerated. As API doc read system.loadLibrary(String libname) allows you to load it from default Java library path or path specified with -Djava.library.path while system.load(String filename) allows you to specify full (absolute) path to the library inside the code. With the second approach you will not need to set java.library.path or LD_LIBRARY_PATH .
Compile Java class nad generate C headers
Compile the Java class and generate JNI header file with necessary declarations.
javac NativeMethodLibrary.java javah -jni NativeMethodLibrary
The generated header file will have #include inside so we will need to specify correct include path when compiling it. It also contains JNI method declaration with single integer argument.
JNIEXPORT jint JNICALL Java_NativeMethodLibrary_root (JNIEnv *, jobject, jint);
Prepare and compile C code of the library
Here is the example code of NativeMethodLibrary.c :
#include "NativeMethodLibrary.h" /* Autogenerated earlier. */ JNIEXPORT jint JNICALL Java_NativeMethodLibrary_root(JNIEnv *env, jobject this, jint number)
Complie native C code with:
gcc -I$JAVA_HOME/include -I$JAVA_HOME/include/linux -o libNativeMethodLibrary.so -shared -fPIC NativeMethodLibrary.c
Note that two include paths are specfied as jni.h resides in include while jni_md.h resides in include/linux . The shared parameter causes a shared object generated that can then be linked with other objects if necessary. The fPIC stands for Position Independent Code. It means the generated code does not have to be located at a specific address in order to work. Code compiled with -fPIC , is suitable for inclusion in a library.
Call native method from Java (command line)
Call the native method from Java if you used System.loadLibrary
java -Djava.library.path=. NativeMethodLibrary
LD_LIBRARY_PATH=. java NativeMethodLibrary 4
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
Note that -Djava.library.path will overwrite LD_LIBRARY_PATH .
The other way is to call the native method from Java if you used System.load
java NativeMethodLibrary 12
The whole cycle is illustrated on below figure.
### Calling native methods from JSP/servlet code
To call native method from JSP the recommended way is to load the library in a class and then instantiate the class in JSP and finally execute native method. Here we needed to move the class into a package test to be able to import the class into JSP as classes of default package cannot be imported. This example is based on tomcat 7.0.37 in JVM Host environment.
cd && mkdir lib javac NativeMethodLibrary.java -d appservers/apache-tomcat-7.0.37/webapps/ROOT/WEB-INF/classes javah -jni -classpath appservers/apache-tomcat-7.0.37/webapps/ROOT/WEB-INF/classes test.NativeMethodLibrary gcc -I$JAVA_HOME/include -I$JAVA_HOME/include/linux -o lib/libNativeMethodLibrary.so -shared -fPIC NativeMethodLibrary.c java -Djava.library.path=lib -classpath appservers/apache-tomcat-7.0.37/webapps/ROOT/WEB-INF/classes test/NativeMethodLibrary 7
Now edit appservers/apache-tomcat-7.0.37/webapps/ROOT/native.jsp and insert:
And finally access the servlet with http://username.jvmhost.net/native.jsp
Notes
- If you get bash: /usr/bin/gcc: Permission denied on a shared host you may have compiler access disabled. Cross compile on a local machine or ask support to enable compilers for you.
- If you get similar error:
/opt/jdk1.6.0_45/include/jni.h:27:20: error: jni_md.h: No such file or directory
then make sure you included platform dependent include directory in gcc command line (specifying just the include directory is not enough as jni_md.h resides in a subdirectory like linux ).
- In case of problems you may also check if the method name exactly matches the declataration in NativeMethodLibrary.h
nm libNativeMethodLibrary.so 00000000000004ec T Java_NativeMethodLibrary_root
As you can see, using native methods in Java is quite simple. In case of any issues please contact JVM Host support.
- © 2016-2023 JVMHost.com All rights are reserved.
Java Language Java Native Interface Loading native libraries
The common idiom for loading shared library files in Java is the following :
public class ClassWithNativeMethods < static < System.loadLibrary("Example"); >public native void someNativeMethod(String arg); .
Calls to System.loadLibrary are almost always static so as to occur during class loading, ensuring that no native method can execute before the shared library has been loaded. However the following is possible :
public class ClassWithNativeMethods < // Call this before using any native method public static void prepareNativeMethods() < System.loadLibrary("Example"); >.
This allows to defer shared library loading until necessary, but requires extra care to avoid java.lang.UnsatisfiedLinkError s.
Target file lookup
Shared library files are searched for in the paths defined by the java.library.path system property, which can be overriden using the -Djava.library.path= JVM argument at runtime :
java -Djava.library.path=path/to/lib/:path/to/other/lib MainClassWithNativeMethods
Watch out for system path separators : for example, Windows uses ; instead of : .
Note that System.loadLibrary resolves library filenames in a platform-dependent manner : the code snippet above expects a file named libExample.so on Linux, and Example.dll on Windows.
An alternative to System.loadLibrary is System.load(String) , which takes the full path to a shared library file, circumventing the java.library.path lookup :
public class ClassWithNativeMethods < static < System.load("/path/to/lib/libExample.so"); >.
PDF — Download Java Language for free
Saved searches
Use saved searches to filter your results more quickly
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.
Native library loader for extracting and loading native libraries from Java.
License
scijava/native-lib-loader
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Sign In Required
Please sign in to use Codespaces.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching Xcode
If nothing happens, download Xcode and try again.
Launching Visual Studio Code
Your codespace will open once ready.
There was a problem preparing your codespace, please try again.
Latest commit
Git stats
Files
Failed to load latest commit information.
README.md
About native library loader
The native library loader is a utility that assists with loading native libraries from Java. It provides the ability to painlessly identify, extract and load the correct platform-specific native library from a JAR file.
Search Maven Central for latest version and add a dependency to your pom.xml.
dependency> groupId>org.scijavagroupId> artifactId>native-lib-loaderartifactId> version>x.y.zversion> dependency>
Native libraries should be packaged into a single jar file, with the following directory & file structure:
/natives /linux_32 libxxx[-vvv].so /linux_64 libxxx[-vvv].so /osx_32 libxxx[-vvv].dylib /osx_64 libxxx[-vvv].dylib /osx_arm64 libxxx[-vvv].dylib /windows_32 xxx[-vvv].dll /windows_64 xxx[-vvv].dll /windows_arm64 xxx[-vvv].dll /aix_32 libxxx[-vvv].so libxxx[-vvv].a /aix_64 libxxx[-vvv].so libxxx[-vvv].a
Here «xxx» is the name of the native library and «-vvv» is an optional version number. Depending on the platform at runtime, a native library will be unpacked into a temporary file and will be loaded from there.
The version information will be grabbed from the MANIFEST.mf file from «Implementation-Version» entry. So it’s recommended to follow Java’s package version information convention.
If you want to load ‘awesome.dll’ (on Windows) or ‘libawesome.so’ (on Linux or AIX), simply do like this .
NativeLoader.loadLibrary("awesome");
About
Native library loader for extracting and loading native libraries from Java.