Open jollyjoker992 opened 6 years ago
also happening here on Android
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Integer.intValue()' on a null object reference
at jnr.ffi.Platform.calculateAddressSize(Platform.java:262)
at jnr.ffi.Platform.<init>(Platform.java:257)
at jnr.ffi.Platform.<init>(Platform.java:29)
at jnr.ffi.Platform$Supported.<init>(Platform.java:415)
at jnr.ffi.Platform$Linux.<init>(Platform.java:464)
at jnr.ffi.Platform.determinePlatform(Platform.java:173)
at jnr.ffi.Platform.determinePlatform(Platform.java:189)
at jnr.ffi.Platform.access$000(Platform.java:29)
at jnr.ffi.Platform$SingletonHolder.<clinit>(Platform.java:38)
at jnr.ffi.Platform.getNativePlatform(Platform.java:292)
at jnr.unixsocket.Native.<clinit>(Native.java:46)
at jnr.unixsocket.Native.socket(Native.java:92)
at jnr.unixsocket.UnixSocketChannel.<init>(UnixSocketChannel.java:101)
at jnr.unixsocket.UnixSocketChannel.open(UnixSocketChannel.java:60)
I think this issue can be closed, as the fix above got merged
@tomholub @headius I'm not so sure... I've been trying to get this very basic example running and having the same issue as OP with jnr-ffi v2.1.10
in the Android Emulator.
// MainActivity.java
// ...
public interface LibC {
@pid_t
long getpid();
@pid_t
long getppid();
}
static {
LibC lib = LibraryLoader.create(LibC.class).load("c");
Log.d("JNR_TEST", "result: " + lib.getpid() + "/" + lib.getppid());
}
// ...
While I've got a testing project set up is there anything else you'd like me to try?
Just tried running it on an actual android device as well (arm8 / aarch64
), this is the latter part of the logcat output.
I have a suspicion that this line has something to do with it:
java.lang.UnsatisfiedLinkError: could not locate stub library in jar file. Tried [jni/aarch64-Linux/libjffi-1.2.so, /jni/aarch64-Linux/libjffi-1.2.so]
Related to jnr/jffi#69 perhaps?
@EternalDeiwos Can you push your testing project somewhere? I can try to reproduce locally.
@headius https://github.com/EternalDeiwos/jnrpid 🙇
Hello; just checking if there has been any further thoughts on this. I reconfigured my test project (linked above) for Android API 29
and tried to run the same example code with jnr-ffi 2.1.16
and 2.2.0
. This produced similar errors to the ones mentioned previously:
Hey I missed this stuff unfortunately but I'm catching up today.
Based on the most recent errors from @EternalDeiwos my first guess would be that the native library part of jffi (the core of jnr) could not be unpacked to an executable location, so it could not be loaded.
jffi does have working support for aarch64-Linux, the platform mentioned in the error, but if that library is not already on the filesystem it must be unpacked from the jar. In terms of Android, I'm not sure exactly what the equivalent behavior would be. How do other Android apps deal with their JNI libraries? It may simply be a matter of injecting the native library into the right place in the application, but my knowledge of how Android apps are structured is limited.
Looping in @donv since he has been maintaining Ruboto and probably knows the answer to this.
Ah; that could possibly make a bit of sense. My knowledge is also quite limited but I have been tinkering a little. Normally you'd just build the library into the app itself. I haven't done it with a prebuilt static lib yet but I have an idea of how to do that. I'll try some things and come back. Any additional suggestions appreciated.
If jffi actively tries to unpack libffi
somewhere privileged then the Android OS would definitely block it from breaking its sandbox...
@EternalDeiwos More recent jffi releases allow specifying a property to unpack the library somewhere else, but that directory would still need to permit loading executable code. Maybe that's helpful?
I suspect the app still needs to make Android aware of the extension, however, and probably pack it in the apk somewhere special.
While poking around; I managed to discover something fairly interesting and I can't figure out what is causing it.
The jni
folder inside my APK contains the jffi libraries for the following architectures:
These native libs are in the correct place to be loaded by android; however this list of architectures is notably missing those most necessary for android. I even rebuilt the current master branch's APK to confirm that it wasn't due to any changes I'd made so far. I don't know what makes these architectures special because I don't specify them anywhere in my code. Does this ring any bells?
Whatever is happening for these architectures is "the correct thing" that would be necessary for it to work for Android; it just needs to provide the appropriate architectures (and ideally not provide the ones that aren't necessary but that's a separate issue).
So I added libffi-1.2
to my project manually (pushed here; not ideal but for good for testing) and I got past the error described above. See the new error below:
This one I do happen to know the cause of; it depends on libc
, which differs for standard linux and android even if built for the same architecture. The way around this is to create a build of libffi
specifically for the android architectures which are compiled using the Android NDK. The good news -- related to jnr/jffi#69 -- is that there are docker images for this.
This of course still does not address why the desired binaries aren't being included in the build without having to manually copy in libffi
; I'll keep digging on that.
@EternalDeiwos This is great progress! Our FFI stub appears to be loading correctly now, at least well enough to attempt to find libc.
One thing that may be related: the necessary native library is installed via a separate maven artifact, and gets downloaded as as separate jar file. Here's a screenshot from search.maven.org showing the native jar artifacts:
It is somewhat confusing that libffi-2.0 would be the missing link here, since the native library that jffi ships should have libffi compiled statically into it.
I also ran across a tool+library today for packaging and loading native libraries from within jar files that could be useful to us if it covers our use cases better than the current ugly code: https://maven-nar.github.io/
Regarding libc... we do have several hacks/tricks in place to try to locate the libc library, which could be improved to support Android's filesystem layout. I am reminded of this issue for Ruby FFI, where we had to fix the JRuby version to always look for "libc.so.6" for reasons: https://github.com/ffi/ffi/issues/824
Let me know how your exploration goes. If necessary I can try to spin up an Android dev environment and look into this, but anything you can do is a great help. JFFI is largely maintained by the JRuby community, so you can chat with us on our Matrix channel: https://matrix.to/#/#jruby:matrix.org
Any update on this?
@bmbariah Yeah I was kinda hoping to hear more back from folks attempting this. Are you having this issue? If I can reproduce it with an easy build or repository maybe we can find a way to fix it now.
Experiencing the same error, i've replicated my error in this repo https://github.com/jaycynth/PlatformJni.git
Hello !@headius Any update on this? I am also getting the same error
Hey, this bug wakes up again!
The problem here is most likely that it is not picking the right platform at that point, because Android is weird.
Can anyone step into the code at that point and see what the OS and CPU values coming back from the runtime actually are? We probably just need to figure out the right way to detect platform on Android.
From what I can find online, the properties we need (os.name and os.arch) should be "Linux" and "aarch64" and that should detect the right platform to load. We will need to step into the Platform.getNativePlatform
call and see why it is unable to determine the platform correctly.
Could this be helpful?
https://simpligility.github.io/android-maven-plugin/native-deps.html
Looks like that probably isn't a necessary dependency.
https://developer.android.com/studio/projects/gradle-external-native-builds
I debug and know that this line causes the java
NullPointerException
when running in Android emulator. It's specific from Sun ? Why don't you make it more common with another solution?Full stack trace