I am trying to transfer an android project from Eclipse to android studio. The project uses a special database called jsqlite. In this library there is a class called jsqlite.Database which has some native functions. When I mouse over those native function I get the message:
Cannot resolve corresponding JNI function Java_jsqlite_Database__1open
Reports native method declarations in Java where no
corresponding JNI function is found in the project
This message is for this native function:
private native void _open(String filename, int mode)
throws jsqlite.Exception;
There are 3 .so files inside the project in those paths:
app\libs\armeabi\libjsqlite.so
app\libs\armeabi-v7a\libjsqlite.so
app\libs\x86\libjsqlite.so
So my guess is that there are on the wrong path. I tried to move them to other positions with no success. Any ideas what to try next?
UPDATE
This is my projects structure:
>app
->manifest
->java
->com.myapp.data
->jsqlite
->jniLibs
->res
You are putting the libraries in the wrong folder.
This should be the correct path:
..\YourProject\app\src\main\jniLibs\armeabi\libjsqlite.so
..\YourProject\app\src\main\jniLibs\armeabi-v7a\libjsqlite.so
..\YourProject\app\src\main\jniLibs\x86\libjsqlite.so
Related
I need some help to use the method "callMethod()" inside ".so" (shared library) in android studio.
My android studio version is 2.1.3.
I created jniLibs folder in "src/main/".
Then I created three folders inside jniLibs folder: (armeabi, armeabi-v7a, x86).
Then I put the .so library inside every mentioned folder.
After that, I updated the build.gradle as follows:
compile fileTree(dir: 'libs', include: ['*.jar','.so'])
In the MainActivity java class I wrote this:
static {
System.loadLibrary("SharedLibAndroid");
}
After that I don't know what should I do.
How do I call the method callMethod() from the .so library?
I searched a lot but I did't see full example how to do that.
I've added to my project new class and native method like below:
#SuppressWarnings("JniMissingFunction")
public class Test1Cpp {
static {
System.loadLibrary("Cpp");
}
public native String callMethod();
}
Then I can call the method inside .so shared library.
I faced another problem, which is my .so library didn't work with all platform mobiles.
The error is:
java.lang.UnsatisfiedLinkError: dlopen failed:
"/data/app/com.mysecondtestapp-1/lib/arm/libCpp.so" has
unexpected e_machine: 3
So, how to convert my .so library to work on all platform mobiles?
I assume that the library does load, otherwise you would get an exception, and I guess you would have mentioned it. So you need to declare the native method you would like to use from the library, and then call it. You can see a simple example here: Sample: hello-jni
The sample source code may be found here: Hello JNI.
Following is the basic working structure:
MainProxy.dll ==> JNIClient.java
Using JNI, I have successfully loaded the MainProxy.dll and able to call the native functions. Following is the required structure:
Main.dll ==> MainProxy.dll ==> JNIClient.java
But when MainProxy.dll compiled and linked with another DLL Main.dll the System.loadLibrary("MainProxy"); call crashed with an exception
Exception in thread "AWT-EventQueue-0" java.lang.UnsatisfiedLinkError: MainProxy.dll: The specified procedure could not be found
However, the MainProxy.dll is successfully compiled and linked against Main.lib and both DLLs are placed to gather with java.
Any idea what causes this issue and how it can be resolved?
Above is the snap from dependencywalker. The ISPVPLPR.dll is the Main.dll and LPRPROXY.DLL is the MainProxy.dll. And the linking between these two looks fine. The CreateNativeClass is exported along with other functions from ISPVPLPR.dll while only CreateNativeClass is imported in LPRPROXY.dll.
Above snap shows that exported native function from LPRProxy.dll
Finally, it turns out that OpenCV pre-compiled libraries was the issue. The ISPVPLPR.DLL was utilizing OpenCV and the copied DLLs were the default that came with setup and were compiled for WinXP Prof 64bit or Win2003 64bit. Since Opencv_Core241.dll requires RtlLookupFunctionEntry and RtlVirtualUnwind functions from Kernel32.dll and these functions were only provided for WinXP and Win2003 Kernel32.dll versions (MSDN Reference).
The solution was simple to recompile the OpenCV2.4.1 for Win7 and with GOD blessings it worked.
I recommend you to use Dependency Walker from microsoft. Use this utility to really check if MainProxy.dll is correctly linked with Main.dll.
If Dependency Walker shows you a problem, tell us how do you compiled and linked MainProxy.dll.
When Dependency Walker shows you no problem, you won't have anymore an java.lang.UnsatisfiedLinkError
I have the following Java native function
private static native void fillEnergyArrays(double currentTemp, double concNA, double concMG);
The function is implemented in C. The code has been tested and I have created a working dynamic library, libhyfiModel.jnilib, which I can use to call the method from a Java file, Temp.java. There are no problems in this case when I run the program with the one file. The method call works and returns the expected value.
The problem:
I am taking Temp.java and libhyfiModel.jnilib and trying to import them into a large IntelliJ IDEA project which uses Maven as a build manager. I have put my libhyfiModel.jnilib file in my correct directory so it loaded when the program executes. I double checked that it's loaded using this code in Temp.java:
static {
try {
System.loadLibrary("hyfiModel");
}
catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load\n" + e);
}
}
No exception is thrown here, so libhyfiModel.jnilib is found and loaded correctly, but when the native method is executed I get the following error:
Exception in thread "main" java.lang.UnsatisfiedLinkError: ca.virology.baseByBase.DiffEditor.fillEnergyArrays(DDD)V
at ca.virology.baseByBase.DiffEditor.fillEnergyArrays(Native Method)
at ca.virology.baseByBase.DiffEditor.main(DiffEditor.java:266)
I have looked at the documentation here https://www.jetbrains.com/idea/help/configuring-module-dependencies-and-libraries.html and followed the instructions with no success.
So the dynamic library is being loaded and I have added the directory containing libhyfiModel.jnilib as a dependency but the method can not execute... What am I missing?
EDIT:
I created a new IntelliJ project with just Temp.java and I am able to call the native function with no errors, so I'm thinking there must be a problem with my project configurations. Any IntelliJ experts out there?
Figured it out. It wasn't a configuration error since the library was being loaded properly. The problem was with Temp.java package membership used in the IntelliJ project.
I had a Temp.h file that was generated using the command javah -jni Temp that contains the C function definitions for my native functions.
I didn't realize that the native function definitions in Temp.h are different when the Java file Temp.java has a specified package.
I found my answer at Another JNI, C++, DLL, UnsatisfiedLinkError <Native Method>
It is shown that the header files' function names change with package membership.
I'm using netbeans 7.4 / jdk 1.7u51
I downloaded the jar for JNA from official site, in version 4.0.0.
I have an internally developped DLL whose interface is in plain C, which loads perfectly well with ctypes in python. This dll is compiled in release with visual 2010, whose runtime are in path.
D:\fl006\Downloads>dir D:\deploy\SpotLight\spotlight-1488\PasanBusLibrary.dll
Directory of D:\deploy\SpotLight\spotlight-1488
29.01.2014 11:13 1'690'112 PasanBusLibrary.dll
I tried to load it in java with jna:
public interface CLibrary extends Library {
(...snip...)
void pasanIpcInitializeLibrary(String xClient, String xBusName, int xTimeout);
void pasanIpcTerminateLibrary();
}
public static void main(String[] args) {
NativeLibrary.addSearchPath("PasanBusLibrary","D:\\deploy\\SpotLight\\spotlight-1488");
CLibrary Bus = (CLibrary) Native.loadLibrary("PasanBusLibrary",CLibrary.class);
(... snip ...)
This is basically an out of the book standard dll load, from a custom location.
When activating jna debug, I see the following :
run:
Looking in classpath from sun.misc.Launcher$AppClassLoader#714a8f44 for /com/sun/jna/win32-x86-64/jnidispatch.dll
Found library resource at jar:file:/D:/code/perso/TestWrapperBus/jna-4.0.0.jar!/com/sun/jna/win32-x86-64/jnidispatch.dll
Looking for library 'PasanBusLibrary'
Adding paths from jna.library.path: null
Trying D:\deploy\SpotLight\spotlight-1488\PasanBusLibrary.dll
Adding system paths: []
Trying D:\deploy\SpotLight\spotlight-1488\PasanBusLibrary.dll
Looking for lib- prefix
Trying libPasanBusLibrary.dll
Looking in classpath from sun.misc.Launcher$AppClassLoader#714a8f44 for PasanBusLibrary
Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library 'PasanBusLibrary': Native library (win32-x86-64/PasanBusLibrary.dll) not found in resource path ([file:/D:/code/perso/TestWrapperBus/jna-4.0.0.jar, file:/D:/code/perso/TestWrapperBus/jna-platform-4.0.0.jar, file:/D:/code/perso/TestWrapperBus/build/classes/])
at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:271)
at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:398)
at com.sun.jna.Library$Handler.<init>(Library.java:147)
at com.sun.jna.Native.loadLibrary(Native.java:412)
at com.sun.jna.Native.loadLibrary(Native.java:391)
at testwrapperbus.TestWrapperBus.main(TestWrapperBus.java:39)
It looks it looks through the location I gave and somehow discards it. I tried different folders and I got same behaviour, there is no obvious file system right issue (dll is RW from all users)
Any clue on what I'm missing, I'm kind of stuck currently...
EDIT
if I load "msvcrt" this is working nice to cll printf
my dll has some dependencies, all of them hosted in c:\windows\system32 (standard runtime, dynamically linked)
My dll is a win32 compilation while I use a win64 JDK / JRE. Of course, when dealing with pure java, we don't care but loading native library needs to match.
I tried running from command line on a 32 bits JRE7 and it worked, so I'm pretty sure that installing JDK for win32 in my netbeans or recompiling my dll in 64 bits will solve the issue.
Thanks to this answer : Trying to use DLL from Java (JNA). Unable to load library exception for having put me on the righteous path
A Java class made for video coding loads a DLL including C++ code
Unpacking debugging symbols for VideoSource.dll to \path
Checking for VideoSource.pdb...
Checking for videosource.pdb...
and then tries to instantiate a native (C++) class from that DLL:
// VideoSource() is implemented in C++ and wrapped with JNI,
// wrapper files were generated with SWIG
_videoProvider = new generated.VideoSource();
That works when the Java class is executed as a JUnit test (video data is extracted).
Same thing does not work when I launch the Java class as an OSGi service.
Essentially, the same code is executed. The DLL is still loaded successfully but the instantiation of the native (C++) class shown above now throws an exception:
java.lang.UnsatisfiedLinkError: generated.VideoSourceSWIGJNI.new_VideoSource()J
What is different when I launch the Java class as an OSGi service instead of executing it as a JUnit test? What can I do to make it work?
BACKGROUND
generated.VideoSource() is
public VideoSource() {
this(VideoSourceSWIGJNI.new_VideoSource(), true);
}
VideoSourceSWIGJNI.new_VideoSource() is
public final static native long new_VideoSource();
C++ implementation is
VideoSource::VideoSource() {
// init frame count
m_frame_cnt = 0;
[..]
}
Thanks, Puce, for pushing me a bit. After asking "would I have to try anything at all"? I got the answer relative quickly:
In order to resume sources (1, 2, 3, 4) with my own words:
When native code, e.g. .so or .dll libraries, shall be used in an OSGi bundle, corresponding libraries have to be declared in the bundle's manifest.
The manifest file may either be edited explicitely, as stated in mentioned sources, or implicitely via an appropriate plugin, e.g. apache felix, when using maven. Used plugin is configured in the POM file and will modify the manifest automatically.