jnr / jffi

Java Foreign Function Interface
Apache License 2.0
168 stars 78 forks source link

Could not load the native lib from jffi-native when launching in Android system #57

Closed jollyjoker992 closed 3 years ago

jollyjoker992 commented 6 years ago

I use jnr-ffi to bind native code to java code but I ran into a problem that cannot detect the CPU size from Platform#calculateAddressSize() because the line of code alway throw error int dataModel = Integer.getInteger("sun.arch.data.model"); So I fix the problem by clone your code and using another system property (os.arch) and rebuild the jar file. After that, I detect another problem in jffi lib that not support arm CPU architecture. The incorrect method is here that it's missing some architecture like i486,i586,i686,i786 (typically is android emulator x86) and arm architecture. So I need to modify code and rebuild the jar file of jffi lib. Everything is OK when I run new code in java app but isn't in Android app. The full stack trace is following

E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.jollyjoker992.bitmarksamplektl, PID: 21303 java.lang.UnsatisfiedLinkError: could not load FFI provider jnr.ffi.provider.jffi.Provider at jnr.ffi.provider.InvalidProvider$1.loadLibrary(InvalidProvider.java:48) at jnr.ffi.LibraryLoader.load(LibraryLoader.java:325) at jnr.ffi.LibraryLoader.load(LibraryLoader.java:304) at cryptography.crypto.libsodium.LibSodium.sodium(LibSodium.java:29) at cryptography.crypto.SecretBox.generateSecretBox(SecretBox.java:27) at sdk.features.Account.generateKeyPair(Account.java:105) at sdk.features.Account.fromSeed(Account.java:47) at com.example.jollyjoker992.bitmarksamplektl.MainActivity.onCreate(MainActivity.kt:24) at android.app.Activity.performCreate(Activity.java:6251) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) at android.app.ActivityThread.-wrap11(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5417) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) Caused by: java.lang.UnsatisfiedLinkError: could not get native definition for type: POINTER at com.kenai.jffi.Type$Builtin.lookupTypeInfo(Type.java:251) at com.kenai.jffi.Type$Builtin.getTypeInfo(Type.java:237) at com.kenai.jffi.Type.resolveSize(Type.java:155) at com.kenai.jffi.Type.size(Type.java:138) at jnr.ffi.provider.jffi.NativeRuntime$TypeDelegate.size(NativeRuntime.java:178) at jnr.ffi.provider.AbstractRuntime.(AbstractRuntime.java:48) at jnr.ffi.provider.jffi.NativeRuntime.(NativeRuntime.java:57) at jnr.ffi.provider.jffi.NativeRuntime.(NativeRuntime.java:41) at jnr.ffi.provider.jffi.NativeRuntime$SingletonHolder.(NativeRuntime.java:53) at jnr.ffi.provider.jffi.NativeRuntime.getInstance(NativeRuntime.java:49) at jnr.ffi.provider.jffi.Provider.(Provider.java:29) at java.lang.Class.newInstance(Native Method) at jnr.ffi.provider.FFIProvider$SystemProviderSingletonHolder.getInstance(FFIProvider.java:68) at jnr.ffi.provider.FFIProvider$SystemProviderSingletonHolder.(FFIProvider.java:57) at jnr.ffi.provider.FFIProvider.getSystemProvider(FFIProvider.java:35) at jnr.ffi.LibraryLoader.create(LibraryLoader.java:73) at cryptography.crypto.libsodium.LibSodium.sodium(LibSodium.java:29)  Disconnected from the target VM, address: 'localhost:8601', transport: 'socket' at cryptography.crypto.SecretBox.generateSecretBox(SecretBox.java:27)  at sdk.features.Account.generateKeyPair(Account.java:105)  at sdk.features.Account.fromSeed(Account.java:47)  at com.example.jollyjoker992.bitmarksamplektl.MainActivity.onCreate(MainActivity.kt:24)  at android.app.Activity.performCreate(Activity.java:6251)  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)  at android.app.ActivityThread.-wrap11(ActivityThread.java)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)  at android.os.Handler.dispatchMessage(Handler.java:102)  at android.os.Looper.loop(Looper.java:148)  at android.app.ActivityThread.main(ActivityThread.java:5417)  at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)  Caused by: java.lang.UnsatisfiedLinkError: java.lang.UnsatisfiedLinkError: could not locate stub library in jar file. Tried [jni/arm-Linux/libjffi-1.2.so, /jni/arm-Linux/libjffi-1.2.so] at com.kenai.jffi.internal.StubLoader.getStubLibraryStream(StubLoader.java:418) at com.kenai.jffi.internal.StubLoader.loadFromJar(StubLoader.java:361) at com.kenai.jffi.internal.StubLoader.load(StubLoader.java:264) at com.kenai.jffi.internal.StubLoader.(StubLoader.java:455) at java.lang.Class.classForName(Native Method) at java.lang.Class.forName(Class.java:324) at com.kenai.jffi.Init.load(Init.java:68) at com.kenai.jffi.Foreign$InstanceHolder.getInstanceHolder(Foreign.java:49) at com.kenai.jffi.Foreign$InstanceHolder.(Foreign.java:45) at com.kenai.jffi.Foreign.getInstance(Foreign.java:103) at com.kenai.jffi.Type$Builtin.lookupTypeInfo(Type.java:242) at com.kenai.jffi.Type$Builtin.getTypeInfo(Type.java:237) at com.kenai.jffi.Type.resolveSize(Type.java:155) at com.kenai.jffi.Type.size(Type.java:138) at jnr.ffi.provider.jffi.NativeRuntime$TypeDelegate.size(NativeRuntime.java:178) at jnr.ffi.provider.AbstractRuntime.(AbstractRuntime.java:48) at jnr.ffi.provider.jffi.NativeRuntime.(NativeRuntime.java:57) at jnr.ffi.provider.jffi.NativeRuntime.(NativeRuntime.java:41) at jnr.ffi.provider.jffi.NativeRuntime$Single

headius commented 6 years ago

Perhaps your final issue would be fixed by #58? The binary we had been shipping for 32-bit ARM was not compiled for hardfp, which seems to be the norm now.

We would be happy to incorporate other changes you made. Please help us make jffi boot properly on Android! 😄

tomholub commented 5 years ago

Related issue that has not been fixed is missing armv7l - my particual Android device arch in https://github.com/jnr/jffi/blob/master/src/main/java/com/kenai/jffi/Platform.java (and likely others as @jollyjoker992 mentioned), plus relying on Integer.getInteger("sun.arch.data.model") which won't work on Android.

tomholub commented 5 years ago

This can be likely closed now

headius commented 3 years ago

@tomholub Right you are! Perhaps someone can submit an example Android app to jnr-ffi-examples that puts things in the right places?