Question

I have to call openssl methods in java e.g android.external.openssl.crypto.pkcs7.PKCS7_encrypt() method. I found that there is no JNI implementation for this. So I have to write JNI layer. Please correct me if I am wrong.

So I learned basic JNI. I found that If I want to call a method e.g search() in java, then method definition in C will be like Java_packageNameOfJavaFile_JavaClassName_method(). Mehotd name says that c/c++ library implementation has to be done after creating header file(*.h file) for native method.

My confusion is If I want to use inbuild library(openssl library) those method doesn't include naming convension as mentioned above, then how should I call those methods in Java.

Was it helpful?

Solution

Basically, you don't call an existing library from Java using JNI; You create a new shared library that exports JNI-compatible functions that happen to use whatever libraries you need to implement them.

To use JNI, you:

  1. decide on a natural, Java-centric model (classes and methods) for the functionality you need
  2. add native to the declaration of the methods
  3. compile the .java files to .class files using javac
  4. run javah on the classes, passing a classpath, which is similar to running java
  5. implement the C functions emitted into the header. (You can use either C or C++ syntax)
  6. if a function implementation requires many Java type conversions or other manipulations in JNI code, go back to the Java class and do the manipulations there, moving native to a private method that is easier to implement in JNI code than the original Java-centric method. (An example of this is string manipulations, where it can be easier for an implementation to consume a Java String as a Java byte[] with the character set/encoding needed by the libraries you use)

A function implementation usually follows the input-processing-output pattern: converting data from the Java parameters into C/C++ data types, calling a library function for processing and then converting data from C/C++ data structures to the Java return object.

You can also create Java objects, call methods and explicitly throw Java exceptions with JNI code.

And always be mindful that a JNI call can leave a Java exception thrown into the JVM, in which case you need to check and branch in your C/C++ code. When you want to leave the exception as thrown, you should stop calling other JNI functions, clean up and exit the function.

And, of course, all C++ exceptions must be caught and handled appropriately.


Alternatives (that actually use JNI under the covers):

  1. SWIG
  2. JNA, JNAerator

These take the opposite approach: take a (sometimes simplified or annotated) C or C++ header and create code that calls functions defined in it. You then might build up a Java model around it to make it more natural to call in your application code.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top