Trouble Installing on Android Device Running Arm Processor

Hello,

I am a beginner into the world of using Maven (got this installed and working) and DL4J and I am trying to install DL4J on my android device (arm processor) by following along with the tutorial posted on the following URL:

After filling in my POM file exactly as described in the tutorial, when I get to the step in the tutorial where I have to package my application (a simple “Hello World” program) by typing “mvn package” I get the following error:

Could not resolve dependencies for project Username-path:example-project:jar:1.0-SNAPSHOT: The following artifacts could not be resolved: org.nd4j:nd4j-native:jar:Android-arm:1.0.0-beta, org . bytedeco . javacpp-presets:openblas:jar:Android-arm:0.2.20-1.4.1: Failure to find org.nd4j:nd4j-native:jar:Android-arm:1.0.0-beta in https :// repo . maven . apache . org/maven2

The tutorial mentions attempting troubleshooting by executing “mvn dependency:tree” but when I do this, I get a very similar error to the above that says:

Could not resolve dependencies for project Username-path:example-project:jar:1.0-SNAPSHOT: The following artifacts could not be resolved: org.nd4j:nd4j-native:jar:Android-arm:1.0.0-beta, org . bytedeco . javacpp-presets:openblas:jar:Android-arm:0 . 2 . 20-1 . 4 . 1: Failure to find org.nd4j:nd4j-native:jar:Android-arm:1.0.0-beta in https: // repo . maven . apache . org/maven2 was cached in the local repository, resolution will not be reattempted until the update interval of central has elapsed or updates are forced

Could someone please tell me what this means and point me in the right direction as to how I should fix this? Does the error mean that I didn’t include some dependencies (i.e. org.nd4j:nd4j-native:jar:Android-arm) in my POM file? If this is the case, what do I write in my POM file in order for the build to be successful so I can do/code some deep learning?

As a new user I can’t have more than 2 snippets of things that look like URLs which my POM file is full of. For the complete picture of what my POM looks like, please see the dubs . tech URL above, only my username and project names are different

Thanks.

For context here also an additional piece that you’ve sent me via DM:

If it makes a difference, I am doing this all on my android device care of the Linux emulator known as Termux (Java 9 and Maven are both installed on my android device). Thanks for any help you can provide.

Now to answer your question:

  1. The DL4J version you are using is very old, about as old as the maven introduction tutorial itself. Because the tutorial isn’t about DL4J, but about Maven, I expected that people would update their version to whatever is the current version
  2. You are doing something that is quite unusual. In all the years that I’ve seen people use dl4j, I haven’t ever seen someone actually try to build a project on an android device itself. For that reason I’m not sure if what you are trying to do is going to actually work.

For building an android application, there is an example here: https://github.com/eclipse/deeplearning4j-examples/tree/master/android-examples

But for what you are trying to do, you may need to try something different. My guess is that it may work for you if you try to build it with one of the following commands:

  • mvn -Djavacpp.platform=linux-armhf
  • mvn -Djavacpp.platform=linux-arm64
  • mvn -Djavacpp.platform=android-arm
  • mvn -Djavacpp.platform=android-arm64

Sounds good. I think I’ll try the second option you gave as a first attempt. Having said that, running the command “mvn -v” returns ‘arch: “arm”’ which is why I’ll specifically try using the command “mvn -Djavacpp.platform=android-arm” as a first shot. I’ll also update the DL4J version to the most recent version in my POM file as you recommend.

I have several follow-up questions:

  1. At what point in the tutorial should I execute the command “mvn -Djavacpp.platform=android-arm” on the command line? Should I execute this new command instead of executing “mvn package” or should I execute “mvn -Djavacpp.platform=android-arm” first and then execute “mvn package” immediately afterwards?

  2. In order to execute your recommended command to try to build my project, should I delete my present project folder created by Maven and restart the whole project from the beginning, or can I just execute the above recommended command with my existing Maven-made folder? I ask this because apparently a decent amount of jar files were downloaded (right before my error crash ocurred) when I first ran the “mvn package” command so I’m not sure if these jar files’ presence would confuse Maven if I try to re-build the project that uses those same jars a second time with my present Maven-made project folder.

  3. Kind of related to question 2), if the specific command I intend to use (“mvn -Djavacpp.platform=android-arm”) fails, can I just re-try, in my existing folder, one of the other commands you suggested, such as “mvn -Djavacpp.platform=linux-armhf”?

Lastly, I looked up the “Djavacpp.platform” Maven command online and found this POM file on Maven’s website (https://repo1.maven.org/maven2/org/bytedeco/javacpp-presets/1.4.1/javacpp-presets-1.4.1.pom). Inside that file, there are many locations where similar looking tags appear, but they’re worded slightly differently:

<javacpp.platform.android-arm>android-arm</javacpp.platform.android-arm>

These are obviously not constructed as Maven commands such as the commands you recommended so I suspect the above XML is for a different purpose. I wasn’t sure if this was related to the commands I’m going to try, but it was the only thing I found online that seemed remotely related to what I’m working with here.

Thanks for your timely response on my last question and the tutorial is amazing for us new guys.

Android doesn’t have a command line and Maven doesn’t run on Android. Please clarify what you’re trying to do.

I am using Termux, which is an app for Android that emulates a linux command line and in that environment I have Java 9 and Maven installed (both are working properly). I’m a complete beginner to Maven and DL4J, but when I followed along on the indicated tutorial, I got an error message at the “mvn package” command step that leads me to believe that I might be missing several dependencies perhaps (?) since Maven reported in the error message that certain dependencies couldn’t be resolved and proceeded to list items pertinent to Android and arm. In short, what I am trying to do is to code, in Java, deep learning programs on my Android device and I would like to set up DL4J on my device to do such.

It’s never been tested with that version of Java. I doubt it will work without some amount of debugging…

The command I suggested is meant to be used whenever you build something, so instead of just mvn package you use mvn -Djavacpp.platform=android-arm package.

Maven is intelligent enough to use what it is supposed to use only. All of those jar files reside outside your project folder anyway (in ~/.m2).

Yes, you can just re-try it.

This configuration option is javacpp specific. Javacpp is something that DL4J uses to access its native code. For more on that specific option see: https://github.com/bytedeco/javacpp-presets/wiki/Reducing-the-Number-of-Dependencies#include-binaries-only-for-one-or-more-platforms

And finally, keep this in mind. Unless your environment turns out to behave more or less like a “normal” Linux system, it is likely that it isn’t going to work at all.

I tried executing “mvn -Djavacpp.platform=android-arm package” and I got the following error

Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project example-project: Compilation failure
/storage/emulated/0/AppProjects/mavenTestProject/example-project/src/main/java/Procambarus-gracilis/github/com/example/App.java:[1,20] ‘;’ expected

Would you please tell me what this error means? I checked inside the java file “App.java” located in the above directory and line 1 is simply my package name:

package Procambarus-gracilis.github.com.example;

Column 20 (I assume this is what’s reffered to by the error’s message of “[1,20]”) is simply the hyphen “-” in my user name which I chose to use for this exercise’s “groupId” in my POM file. Is the hyphen not supposed to be used as part of “groupId” names? Thanks.

You can use it as part of your group Id, but when it creates the initial files, it doesn’t do any magic, it does just simple string replacement.

The error you see is java complaining about a file it can’t compile.

As for trying to run dl4j in your environment, maybe you should start with something as simple as possible. Clone the examples repository from github, and then try to run the mvn-project-template.

I felt gutsy and removed the hyphen from my “groupId” tag in my POM file and the package names in 2 Java files and re-tried the command. It seems to have worked as it gave me “Build successful”. I had to remove the hyphen from inside both the Java files’ package names - the two Java files are called “AppTest.java” and “App.java” - in order to get the “Build successful” message which returned me to my standard command line input (a “$” for my Linux version) with no errors reported. Consequently the step I’m at now (I think) is learning how to run the program (is it compiled and ready to run by having run that Maven command? Do I need to compile it? How would I compile it if I still need to compile it? etc…). I’ll check out your tutorial to see how the Java file with my main method is compiled and run and what the next steps are.

With regards to the github project you referred me to clone in your most recent response, do I just clone it to a folder somewhere on my local machine and run the special Maven command (“mvn -Djavacpp.platform=android-arm package”) in the directory/folder that contains the included POM file? Thanks.

You should have a jar file now in the target folder. So you can run it with java -cp target/your-file.jar your.main.class

You clone it to the device where you are doing all the things you are trying to do here. Or if you can’t clone it directly there, you can clone it to your local machine and copy over just that specific folder.

Take a look around in that project, there are almost no files there. It has the pom.xml file for maven. A logback.xml file in the resources folder, to configure the logger that dl4j uses and finally a single class is defined that trains a simple network on MNIST.

Awesome. Yes indeed, I have the “target” folder you just described but I have 2 jar files: one called “example-project-1.0-SNAPSHOT.jar” and the other called “original-example-project-1.0-SNAPSHOT.jar”. If I remember correctly from the tutorial, the one that does not have the prefix “original” is the one that has all of the dependencies packaged in it (if I remember correctly, this is he uber jar) and this is the one I want to run at this point.

I do have git on my device in order to clone githubs so I’ll also play around with the github you mentioned then too. Thanks.

Ok, so for the LeNetMNIST example, I have tried running it with the following command:

java -cp deeplearning4j-example-sample-1.0.0-beta7-bin.jar org.deeplearning4j.examples.sample.LeNetMNIST

I got the following error which leads me to believe I am missing a dependency (a quick Google search indicated someone who got a very similar compile error and it seems like the diagnosis was that they needed an additional jar file in their dependencies in the POM file). Here is my specific error (I’ve added emphasis on what caught my eye by bolding it):

Warning: Could not load Loader: java.lang.UnsatisfiedLinkError: no jnijavacpp in java.library.path
Exception in thread “main” java.lang.ExceptionInInitializerError
at org.nd4j.linalg.cpu.nativecpu.ops.NativeOpExecutioner.(NativeOpExecutioner.java:86)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:488)
at java.base/java.lang.Class.newInstance(Class.java:558)
at org.nd4j.linalg.factory.Nd4j.initWithBackend(Nd4j.java:5178)
at org.nd4j.linalg.factory.Nd4j.initContext(Nd4j.java:5092)
at org.nd4j.linalg.factory.Nd4j.(Nd4j.java:270)
at org.deeplearning4j.nn.conf.NeuralNetConfiguration$Builder.seed(NeuralNetConfiguration.java:579)
at org.deeplearning4j.examples.sample.LeNetMNIST.main(LeNetMNIST.java:65)
Caused by: java.lang.RuntimeException: ND4J is probably missing dependencies. For more information, please refer to: https://deeplearning4j.konduit.ai/nd4j/backend
at org.nd4j.nativeblas.NativeOpsHolder.(NativeOpsHolder.java:112)
at org.nd4j.nativeblas.NativeOpsHolder.(NativeOpsHolder.java:35)
… 11 more

Caused by: java.lang.UnsatisfiedLinkError: no jniopenblas_nolapack in java.library.path
at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2541)
at java.base/java.lang.Runtime.loadLibrary0(Runtime.java:873)
at java.base/java.lang.System.loadLibrary(System.java:1857)
at org.bytedeco.javacpp.Loader.loadLibrary(Loader.java:1631)
at org.bytedeco.javacpp.Loader.load(Loader.java:1265)
at org.bytedeco.javacpp.Loader.load(Loader.java:1109)
at org.bytedeco.openblas.global.openblas_nolapack.(openblas_nolapack.java:12)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:375)
at org.bytedeco.javacpp.Loader.load(Loader.java:1176)
at org.bytedeco.javacpp.Loader.load(Loader.java:1109)
at org.nd4j.nativeblas.Nd4jCpu.(Nd4jCpu.java:14)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:292)
at org.nd4j.nativeblas.NativeOpsHolder.(NativeOpsHolder.java:85)
… 12 more
Caused by: java.lang.UnsatisfiedLinkError: no openblas in java.library.path
at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2541)
at java.base/java.lang.Runtime.loadLibrary0(Runtime.java:873)
at java.base/java.lang.System.loadLibrary(System.java:1857)
at org.bytedeco.javacpp.Loader.loadLibrary(Loader.java:1631)
at org.bytedeco.javacpp.Loader.load(Loader.java:1213)
… 22 more

Would you please tell me if I indeed need more dependencies in my POM file in order to eliminate the error? If I do need more dependencies, would you please direct me to how they should be invoked in my POM file?

If this error refers to something else, would you please explain to me what it means?

Thanks.

Set the “org.bytedeco.javacpp.logger.debug” system property to “true” to get more information about what it’s failing to load.

Where do I set this to true? Is that in POM file somewhere?

Also just to be sure, and I ask this because I am inexperienced with Maven, whenever I make a change in the POM file if I’m requesting new dependencies or whatnot, do I just always rebuild my entire project with the “mvn package” command in order to get a new uber jar with the new dependencies incorporated and ready to run?

You can set it via your java -cp ... command like this:
java -Dorg.bytedeco.javacpp.logger.debug=true -cp ...

Ok, I ran the debugging command as part of my execution of the jar file like you suggested and when I tried to execute the program I got the same errors along with the following debugging details:

Debug: Loading class org.bytedeco.javacpp.presets.javacpp
Debug: Loading class org.bytedeco.javacpp.Loader
Debug: Loading library jnijavacpp
Debug: Failed to load for jnijavacpp: java.lang.UnsatisfiedLinkError: no jnijavacpp in java.library.path
Warning: Could not load Loader: java.lang.UnsatisfiedLinkError: no jnijavacpp in java.library.path
Debug: Loading class org.bytedeco.javacpp.presets.javacpp
Debug: Loading class org.bytedeco.openblas.global.openblas_nolapack
Debug: Loading class org.bytedeco.javacpp.presets.javacpp
Debug: Loading class org.bytedeco.openblas.global.openblas_nolapack
Debug: Loading library
Debug: Failed to load for : java.lang.UnsatisfiedLinkError: no in java.library.path
Debug: Loading library openblas
Debug: Failed to load for openblas: java.lang.UnsatisfiedLinkError: no openblas in java.library.path
Debug: Loading library jniopenblas_nolapack
Debug: Failed to load for jniopenblas_nolapack: java.lang.UnsatisfiedLinkError: no jniopenblas_nolapack in java.library.path

I tried re-building it with two additional dependencies in my POM file for the “no openblas” and “no jniopenblas_nolapack” errors (someone on a Stacked Overflow said including these 2 dependencies fixed what appears to be a similar, but not the same, error for them), but I still keep getting the “no jniopenblas_nolapack in java.library.path” and the “no openblas in java.library.path” error output. Admittedly, these 2 dependencies are supposed to take care of the “no jniopenblas in java.library.path” error, which isn’t one of my errors but I thought I’d try it anyways. Here are the 2 dependencies (I replaced some brackets with parentheses because the system was outputting something else):

(groupId>org.bytedeco.javacpp-presets(/groupId>
(artifactId>openblas(/artifactId>
(version>0.2.20-1.4(/version>
(/dependency>

(dependency>
(groupId>org.bytedeco.javacpp-presets(/groupId>
(artifactId>openblas-platform(/artifactId>
(version>0.2.20-1.4(/version>
(/dependency>

From the debugging output, are there any thoughts on what might be causing the error? Thanks.

Binaries for OpenBLAS are missing, yes. They will need to be part of the class path, or in your case part of the uber JAR. You’ll need to figure out why that isn’t the case. What are the files in the uber JAR?

My guess is that the chosen platform isn’t actually working.

In addition to answering @saudet 's question, please also try the other options that I’ve given you in my initial answer.

How can I check/see what files are in the uber jar? Is it just the list of dependencies in my POM file?