Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support to 64 bit devices for Android #76

Closed
lidord opened this issue Jul 1, 2015 · 19 comments
Closed

Add support to 64 bit devices for Android #76

lidord opened this issue Jul 1, 2015 · 19 comments

Comments

@lidord
Copy link

lidord commented Jul 1, 2015

Today you support only x86 and arm v7, devices with x86_64 for example can't run your code. Please add more jni libs for 64 bit..
This is the error I've got today:

Caused by: java.lang.UnsatisfiedLinkError: Could not load J2V8 library. Reasons:
Couldn't load j2v8_android_x86_64 from loader dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.my-app.apk"],nativeLibraryDirectories=[/data/app-lib/com.my-app-2, /vendor/lib, /system/lib, /system/lib/arm]]]: findLibrary returned null

Thanks for this great site and support !!

Thanks a lot for this great library

@mpost
Copy link
Member

mpost commented Jul 1, 2015

I can confirm the issue.

As a temporary workaround you can place the libj2v8_android_aarch64.so into your android project under src/main/jniLibs/armeabi

@lidord
Copy link
Author

lidord commented Jul 1, 2015

Thanks, but where can I find the libj2v8_android_aarch64.so? in your jar in maven there are only the arm7i.so and x86.so..

@mpost
Copy link
Member

mpost commented Jul 2, 2015

Ups sorry... you can just rename the regular 32bit .so from project.

@lidord
Copy link
Author

lidord commented Jul 2, 2015

Thanks again, I need to clarify:
Today I have 2 folders under jniLibs:

  1. armeabi-v7a folder, which has libj2v8_android_armv7l.so inside
  2. x86 folder, which has libj2v8_android_x86.so
  3. You wrote me to add another folder (3rd folder) and to name it armeabi, and add libj2v8_android_aarch64.so into it.

What about x86_64? should I rename current libj2v8_android_x86.so to something else? and under which folder should I add the x86_64?

Thanks :)

@mpost
Copy link
Member

mpost commented Jul 2, 2015

I read your question wrong. My guess is that it works out of the box with x86 64bit since i do nothing special and can still deploy to an x86 64bit emulator. The subfolder workaround i mentioned above applies to 64bit arm support.

@lidord
Copy link
Author

lidord commented Jul 2, 2015

We got exceptions on Android Asus devices running 64 bit, as you can see that the problem is "couldn't find j2v8_android_x86_64":

Couldn't load j2v8_android_x86_64 from loader dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.my-app.apk"],nativeLibraryDirectories=[/data/app-lib/com.my-app-2, /vendor/lib, /system/lib, /system/lib/arm]]]: findLibrary returned null

Thanks again!

@mpost
Copy link
Member

mpost commented Jul 2, 2015

I am pretty certain with the right combination of file name and folder structure it also works on on x86 64bit support. Maybe @irbull has got an idea.

@achaudhry
Copy link

Hello gents,

I'm having a similar issue on my 64 bit phone (Samsung s6 Egde). In my case libj2v8_android_armv7l.so is 32-bit instead of 64-bit seems to be the key. I'm using the latest jar (v3.0). Any guidance is much appreciated!

Thanks in advance!

Stack Trace
Caused by: java.lang.UnsatisfiedLinkError: Could not load J2V8 library. Reasons:
dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.myapp-2/base.apk"],nativeLibraryDirectories=[/vendor/lib64, /system/lib64]]] couldn't find "libj2v8_android_armv7l.so"
dlopen failed: "/data/data/com.myapp/libj2v8_android_armv7l.so" is 32-bit instead of 64-bit
at com.eclipsesource.v8.LibraryLoader.loadLibrary(LibraryLoader.java:71)
at com.eclipsesource.v8.V8.load(V8.java:69)
at com.eclipsesource.v8.V8.createV8Runtime(V8.java:131)

Edited: @irbull, I wasn't sure if you were getting notifications of this thread so I thought I should give you a nudge to see if this rings a bell? Thanks again!

@irbull
Copy link
Member

irbull commented Jul 20, 2015

I don't have an x86_64 based phone to test this on. There are two questions here:

  1. Does the 32 bit .so file work if it's placed in the right spot (and has the right name)
  2. If not, does V8 3.26 support x86_64 and do we need to build for Yet Another Architecture?

Has anybody managed to extra the .so file, place it in a jniLibs directory and get it to load? If so, can you update us with the .so file you used and the naming scheme that worked?

@zhm
Copy link

zhm commented Jul 20, 2015

This is what is working for us so far. We were getting the same x86_64 load errors when using the Android emulator. When we added the 32bit version named as the 64bit binary, it works. I think the issue is a combination of Android's System.loadLibrary behavior and the hardcoded file names inside the J2V8 loader.

├── jniLibs
    ├── armeabi
    │   └── libj2v8_android_armv7l.so
    └── x86
        ├── libj2v8_android_x86.so
        └── libj2v8_android_x86_64.so

Here it's hardcoded to look for the lib name with x86_64 in the name. The trick with the current available version of J2V8 is to get it to load the lib here instead of here because the first one ultimately results in System.loadLibrary which invokes some fallback logic, whereas System.load explicitly tries to load the full file path and fails if the architecture doesn't match exactly. I think on Android, ideally it should use the System.loadLibrary and through some mechanism of project configuration changes and build config, the files are in the correct directory structure without needing to manually add the files to the project?

@irbull
Copy link
Member

irbull commented Jul 20, 2015

The problem is that System.loadLibrary only loads from pre-defined places, and J2V8 cannot write to any of those places on Android (that is, we cannot unpack the lib and place it in one of those pre-defined places). System.load allows us to specify a full path, but it doesn't use the fallback mechanism.

It's good to know that the existing native bits work, but we all might have to package them up in places like the jniLibs directory ourselves :(.

@zhm
Copy link

zhm commented Jul 20, 2015

Also note that in my listing, libj2v8_android_x86.so and libj2v8_android_x86_64.so are copies of the same file. It's obviously not ideal, but it seems to work.

I think on Android what would work well is to use the same "library short name" for all architectures and call System.loadLibrary("j2v8_android") and have the OS figure out which version of libj2v8_android.so to load.

A directory structure like this would work I think:

├── jniLibs
    ├── armeabi-v7a
    │   └── libj2v8_android.so
    └── arm64-v8a
    │   └── libj2v8_android.so
    └── x86
    │   └── libj2v8_android.so
    └── x86_64
        └── libj2v8_android.so

@zhm
Copy link

zhm commented Jul 20, 2015

@irbull makes sense. Is there a way to package the entire lib so that it can be added as a dependency in gradle and have everything "just work" and the libs are in the correct System.loadLibrary-compatible locations when it builds? In other words, is extracting necessary? Or is it just a result of the way the project files are setup currently?

@achaudhry
Copy link

@irbull So a couple of things:

  1. I'm using the JAR file and it only has two .so files i.e. libj2v8_android_armv7l.so and libj2v8_android_x86.so. libj2v8_android_armv7l.so gets loaded for 32 bit devices and works well.
  2. In my case, in LibraryLoader the System.getProperty("os.arch") method returns aarch64 and according to this it also loads libj2v8_android_armv7l.so which fails for 64 bit devices.

Furthermore, I'm not sure where to find libj2v8_android_x86_64.so but even if I did, I don't think it will work because Library loader is explicitly loading libj2v8_android_armv7l.so. Does this make sense?

Thanks all for your help!

@irbull
Copy link
Member

irbull commented Jul 20, 2015

@achaudhry There are some fallback modes on Android. As @zhm mentioned libj2v8_android_x86.so and libj2v8_android_x86_64.so are copies of the same file.

So, I think what you need to do is create a jniLibs directory, and use the same directory structure mentioned above.

├── jniLibs
    ├── armeabi
    │   └── libj2v8_android_armv7l.so
    └── x86
        ├── libj2v8_android_x86.so
        └── libj2v8_android_x86_64.so

If there is anything in the jniLibs directory, then that takes precedence in the library loader and it will use that (it first tries a loadLibrary which loads from here, and if that fails, it falls-back to the os.arch loading).

@achaudhry
Copy link

@irbull I see, makes sense!

Sorry if this is a stupid question but, where can I get the .so files from? And where exactly am I creating the jniLibs directory i.e. what should be the package structure?

Thanks
Abrar

@achaudhry
Copy link

OK awesome that worked!! 👍 👍

@anisart
Copy link

anisart commented Aug 24, 2015

@irbull you can use remote 64-bit device, for example Samsung Galaxy S6, http://developer.samsung.com/remotetestlab/rtlDeviceList.action

When will the new version in maven? Or I should build 64-bit version from source, right?

@irbull
Copy link
Member

irbull commented Jan 10, 2019

This is working now, and I will be publishing binaries. This was mostly done in #384. Closing this as duplicate (even though this was opened first).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants