Use library module with JNI in application module Android library module - java

I have a project with 3 modules - a library and 2 apps that using this library. Now I want to add native-lib (one c file) into the library module, and use it in one of the library classes. I'm new to NDK so I followed the Google guide and created new project with NDK support and it works fine.
Then I copy the cpp directory, CMakeList, and kept the correct structure of the project.
Now, what happening is that the project compiles successfully, but crashes when I trying to call the native func from java class.
Exception: Method threw 'java.lang.UnsatisfiedLinkError' exception.

I had this exception with a subsequent ClassNotFoundException when I wrote a Java library that referenced other native libraries. I didn't use NDK like you did, but maybe these steps (that solved it for me) can provide you some new ideas:
I imported the native library (for me it was OpenCV for Java) in AndroidStudio as a library.
I put the native source files in the jniLibs folder of the (imported) library.
Then I exported the library as AAR file. (Make Module -> take out the AAR from /build/outputs/aar/)
I used the AAR file in my own library. That way the classes of the referenced native library could be used in my own exported library.

Related

How to access jar file through Xamarin Forms

I have a Xamarin project and an android bindings library that has a jar file attached. How can I call a function from the jar library. For example, so that when a button is pressed, a function from the library is called.
Sample project:
For this, you can check document Binding a .JAR.
The Android community offers many Java libraries that you may want to use in your app. These Java libraries are often packaged in .JAR (Java Archive) format, but you can package a .JAR it in a Java Bindings Library so that its functionality is available to Xamarin.Android apps. The purpose of the Java Bindings library is to make the APIs in the .JAR file available to C# code through automatically-generated code wrappers.
Xamarin tooling can generate a Bindings Library from one or more input .JAR files. The Bindings Library (.DLL assembly) contains the following:
The contents of the original .JAR file(s).
Managed Callable Wrappers (MCW), which are C# types that wrap
corresponding Java types within the .JAR file(s).
The generated MCW code uses JNI (Java Native Interface) to forward your API calls to the underlying .JAR file. You can create bindings libraries for any .JAR file that was originally targeted to be used with Android (note that Xamarin tooling does not currently support the binding of non-Android Java libraries). You can also elect to build the Bindings Library without including the contents of the .JAR file so that the DLL has a dependency on the .JAR at runtime.
For more information, you can check: Binding a Java Library .

Why is Android Studio giving me an error about .so files when I try to add a .jar file as a dependency?

I am trying to add a .jar file to my company's app. I added it to app\libs, and added the dependency to my gradle file as implementation files('libs\\libname.jar). Android Studio detects the imported classes and everything, but when I go to build and run my app, it immediately crashes with the following error: Failed to load libname.so. Make sure the jni symbols are accessible somehow. I'm not sure why it is talking about an .so file and jni symbols, but I'm guessing it's related. There is also an example app for this .jar library but it also crashes with the same error.
The JAR contains a reference to a JNI library that it is trying to load. You are not including the corresponding .so file.
My guess is that this JAR is not set up for use with Android. If it is, look for an AAR file, preferably via a Maven repository reference rather than a bare file, and use it.

Google Or-Tools : UnsatisfiedLinkError

I have created a spring application which uses google or-tools. For that, I am importing jniortools using System.loadLibrary("jniortools"). when I provide the .dll file and run the war file it runs perfectly. But when I provide the .so file path in lib, I get the unsatisfiedlinkerror.
Taken from here, a solution for using or-tools over Intellij:
To make it work using Intellij (over a windows machine) you need to:
Install Microsoft Visual C++ Redistributable for Visual Studio
Download and extract the OR-Tools library for Java
In intellij, add jar dependency to the 2 jars under the lib folder of the extracted files (each of the 2 jars separately, do not add to lib folder itself. This is why).
Add the lib library path to VM options. In Intellij edit your run-configuration and add to vm options: -Djava.library.path=<path to the lib folder that hold the jars>
Load the jni library statically by adding the below code to your class (as mentioned here.)
static {
System.loadLibrary("jniortools");
}

Converting android library project to jar file

I have a create an android library project which has to be given to a 3rd party application,I have two requirements,
1)convert the library project into a jar file (or),
2)Make the source code in the library project obfuscated.
Basically i dont want to 3rd party application developer to get my source code.
Please help! thanks in advance!
The ProGuard-Application lets you shrink and obfuscate your code. It is from the Android developers, so you can assume it is safe to use it.
This is the closest that you can get:
1: Create a regular Android library project, and get it working.
2: Copy that Android library project into another directory.
3: Create a JAR from the compiled Java classes from the original Android library project, and put that JAR in the libs/ directory of the copy you made in Step #2. You should be able to run ProGuard on this JAR manually, though I haven't tried that.
4: Remove everything inside the src/ directory of the copied library project, leaving behind and empty src/ directory.
5: ZIP up or otherwise distribute the copied Android library project.
This is what you need to do:
Create your library project. Write a test application that tests your library. Build your library project. You could use ant/maven through eclipse. Most libraries now need gradle support because applications are now using Android Studio. Mark your project as a library by going to Project -> Properties -> Android and select the Is Library checkbox. Check this link: http://developer.android.com/tools/projects/projects-eclipse.html.
If you don't want a 3rd party app developer to see your source files, you need to enable proguard. This tool shrinks, obfuscates your code. The application that uses your library has a lot of control over what code needs obfuscation. For example, an application can decide that it wants all packages starting with com.blah.blah* to not be obfuscated by specifying the -keep option in its proguard config file. This will prevent certain sections of code from getting obfuscated. You should allow default obfuscation for libraries unless you decide to use components which don't function with obfuscation (like annotations or reflections).
By enabling proguard, a third party developer will not get access to your source on reverse-engineering your apk. Use wisely!

Using JNI libraries in an Eclipse Java project

I have inherited a jar file with two JNI class files and related libraries (.so files). I am not familiar with c++ or JNI. How do I reference these in my Java project in Eclipse?
So far, I have created a Java project, added the jar file as an external jar to the buildpath and then have attached the folder containing the jni libraries using Properties -> Java Build Path -> Libraries tab, expand the jar file (containing the class files) and edit "Native library location".
I have a driver program in Java with a main method which makes the jni object. Eclipse says "ObjectName cannot be resolved to a type".
Why would this happen even though the class files are in the build path?
I have just put all the libraries under /src/main/resources.
Right click on the project and go to Properties>JavaBuildPath. In the Libraries section expand the jar you need the libraries for and click on "Native library location", then press "Edit..".
You just need to give the /src/main/resources path as location.
Then in the "Order and Export" section of the Properties>JavaBuildPath you need to make sure that /src/main/java is above /src/main/resources.
In the Java file, where you instanciate your JNI defined object, make sure you have imported the class files:
import your.jni.classes;
I suggest you have a look here, at the video:
http://mmbtools.crc.ca/content/view/53/78/
(look at this video on Youtube and set the resolution to 720px to see clearly)
It is a good step-by-step example of how to integrate JNI classes in a Java application, in Eclipse. It is pretty much what you're trying to do.
Hope it helps,

Categories