Troubles with launching DL4J on Android

Hello there!
Recently I was trying to launch DL4J on Android and encountered some troubles. I used the tutorial from the docs explaining how to do it and example project from the DL4J repository. And when I tryed to build the project it just failed with the message saying:

More than one file was found with OS independent path ‘META-INF/native-image/android-arm/jnijavacpp/reflect-config.json’

Ok, I just added this path to exclude in packagingOptions block. But then the same fail appeared 23 times, each time with different path. It was not amusing to add exclude for 23 times, each time waiting for 2 minutes of project building and failing. Anyway I added all path to exclude and now my packagingOptions block in build.gradle looks like:

    packagingOptions {
        exclude 'META-INF/native-image/linux-ppc64le/jnijavacpp/reflect-config.json'
        exclude 'META-INF/native-image/windows-x86/jnijavacpp/jni-config.json'
        exclude 'META-INF/native-image/android-x86_64/jnijavacpp/reflect-config.json'
        exclude 'META-INF/native-image/linux-ppc64le/jnijavacpp/jni-config.json'
        exclude 'META-INF/native-image/linux-x86_64/jnijavacpp/jni-config.json'
        exclude 'META-INF/native-image/macosx-x86_64/jnijavacpp/reflect-config.json'
        exclude 'META-INF/native-image/windows-x86/jnijavacpp/reflect-config.json'
        exclude 'META-INF/native-image/linux-arm64/jnijavacpp/reflect-config.json'
        exclude 'META-INF/native-image/linux-x86/jnijavacpp/jni-config.json'
        exclude 'META-INF/native-image/linux-x86_64/jnijavacpp/reflect-config.json'
        pickFirst 'nd4j-native.properties'
        exclude 'META-INF/native-image/linux-arm64/jnijavacpp/jni-config.json'
        exclude 'META-INF/native-image/android-x86_64/jnijavacpp/jni-config.json'
        exclude 'META-INF/native-image/android-x86/jnijavacpp/jni-config.json'
        exclude 'META-INF/native-image/linux-armhf/jnijavacpp/reflect-config.json'
        exclude 'META-INF/native-image/android-arm64/jnijavacpp/reflect-config.json'
        exclude 'META-INF/native-image/linux-x86/jnijavacpp/reflect-config.json'
        exclude 'META-INF/native-image/android-arm/jnijavacpp/jni-config.json'
        exclude 'META-INF/native-image/android-x86/jnijavacpp/reflect-config.json'
        exclude 'META-INF/native-image/linux-armhf/jnijavacpp/jni-config.json'
        exclude 'META-INF/native-image/android-arm64/jnijavacpp/jni-config.json'
        exclude 'META-INF/native-image/windows-x86_64/jnijavacpp/reflect-config.json'
        exclude 'META-INF/native-image/macosx-x86_64/jnijavacpp/jni-config.json'
        exclude 'META-INF/native-image/windows-x86_64/jnijavacpp/jni-config.json'
        exclude 'META-INF/native-image/android-arm/jnijavacpp/reflect-config.json'

        
    }

I thought ‘Finnaly, I’m able to build and run this successfully!’, but I’ve never been so wrong before… So, the build was really successful, but now the installation on the emulator failed with the message:

Installation did not succeed.
The application could not be installed: INSTALL_FAILED_INVALID_APK

I searched trough a lot of sites and articles on google… The only solution that solved the problem is to downgrade gradle version to 3.5.x (at least 3.5.0 and 3.5.4 work well). At last, the project builded and installed successfully.

I do not understand why I have to do so many body movements and break my brain to run DL4J on Android and why there is nothing said in the DL4J docs about these problems.
So the question is: is there any way to launch DL4J on Android without excluding so many files and downgrading the gradle each time I create new project with DL4J?

@UnDan so let’s break this down a bit…generally for running android apps we’re just a library with some embedded c++ code for running math. The main issues should be around:

  1. Dependency size - the binary size is usually an issue for users

Regarding The META-INF/native image stuff specifically is mainly for graalvm. If you aren’t using that, you can actually exclude those files if you want.

I’ll ping @saudet here as well since the bulk of this is javacpp related.

He might be able to have a recommendation for you.

Beyond that, please consider that there are humans maintaining this code like you. We just want to help here on the forum. I know you’re frustrated and I can’t imagine it’s easy.

If you can work with us rather than be antagonistic, we can try to get a good outcome here for both of us. We didn’t wake up and give you free code to purposely make your life hell. Please consider that when interacting with us from here on out.

Now, more on to your problem: let’s try to work together and we’d be happy to document some of these things. The problem you’re facing hasn’t come up with users. I documented above what generally people have problems with. Apologies again for the outcome here.

Could you give us a way to reproduce this? Versions of whatever you have would help. I can’t really run code that reproduces your problem without some sort of an indicator on where to begin.

We can easily exclude all those files with a single line like this:

And that sample project itself works fine with the most recent versions of Android Studio and Gradle, so I don’t know why you’re encountering errors with them, but it’s most likely unrelated to DL4J or JavaCPP.

Thanks for fast reply. I understand what you said and apologize if my words were rude, I did not mean to insult anyone.
I’m ready to work together to solve the problem, at least to make using DL4J on Android easier for me and other users.
So, as I said, I just took android example from DL4J repository: deeplearning4j-examples/android-examples at master · eclipse/deeplearning4j-examples · GitHub then tried to launch it on Android Studio 4.2.0 and encountered problems that I have described above.
Anyway, even when I created my own project using code for build.gradle in the docs (https://deeplearning4j.konduit.ai/v/en-1.0.0-beta7/android/setup) the same problems were encountered.
If there is anything I can do to help you understand the situation more, please tell me and I’ll try do my best.

Thanks a lot @UnDan I think some work on that example needs to be done looking at it. Apologies, but the main testing we’ve been doing: https://deeplearning4j.konduit.ai/multi-project/how-to-guides/developer-docs/javacpp

Please ensure that you use the latest version (1.0.0-M1.1) the android integration is much faster with armcompute integrated. I assume you are if you are using the example there.

Let me take a closer look at the example and get back to you. If you can just for now try to include it in your app and seeing if something minimal works that would be really helpful.

If you could clarify how you’re testing (like android studio, run on emulator, real phone etc) I can try to reproduce your workflow and document the workflow there better.

Unfortunately it’s my late night now so I’ll have to resume looking at this tomorrow.

Yes, I use the 1.0.0-M1.1 version:

def dl4jVersion = '1.0.0-M1.1'

I’m testing and running the app on emulator with Android 10 (api 29)

@UnDan thanks a lot. Let me take a look a this.

Also, did you make sure to set android:extractNativeLibs=“true”? See the following issue:

@UnDan JFYI I did try to look in to this but ran in to issues with hyper v + windows 11. I have a bit of developer environment issues to sort out. I do have my arm based pi setup that already runs android 11 natively, if there’s something specific you want me to test I can try on there. I usually verify the binaries in termux.