# Android ND4J conflicts with gRPC

**URL:** <https://community.konduit.ai/t/android-nd4j-conflicts-with-grpc/1810>\
**Category:** ND4J\
**Created:** [March 22, 2022, 3:57pm UTC](https://community.konduit.ai/t/android-nd4j-conflicts-with-grpc/1810 "2022-03-22T15:57:33Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![UnDan](https://avatars.discourse-cdn.com/v4/letter/u/ac91a4/32.png) [@UnDan](https://community.konduit.ai/u/UnDan)\
**Post date:** [March 22, 2022, 3:57pm UTC](https://community.konduit.ai/t/android-nd4j-conflicts-with-grpc/1810/1 "2022-03-22T15:57:33Z")

</div>

Hello there!  
I am a student and I am currently developing (as my bachelor’s degree task) an Android application that uses **DL4J** , **ND4J** and **gRPC** libraries. Not long ago I encountered a problem that I have tried to fix myself, but eventually it just turned out as a waste of my time. So here I am now, hoping to find the solution.

**1. What exactly is going on?**

- My team is currently developing a java library for _federated learning_. The library have been tested and now it’s used by another team developing a _web application_ (both the client and the server) for federated learning. As far as I know, this application works perfectly, so the library too.
- My task is to develop an Android application that will be used as _federated learning client_. This application uses my team’s library too (with minor changes for using it on Android).
- The library consists of 2 modules: **‘framework’** (client-server communication using _gRPC_ protocol, data reading, etc.) and **‘deeplearning’** (for NN learning, obviously).

**2. What problems have I encountered with (and how have I tried to fix them)?**

1. When I try to build the application the _‘checkDebugDuplicateClasses’_ task fails with the message:

```auto
Duplicate class com.google.thirdparty.publicsuffix.PublicSuffixPatterns found in modules guava-30.1.1-android.jar (com.google.guava:guava:30.1.1-android) and protobuf-1.0.0-M1.1.jar (org.nd4j:protobuf:1.0.0-M1.1)
Duplicate class com.google.thirdparty.publicsuffix.PublicSuffixType found in modules guava-30.1.1-android.jar (com.google.guava:guava:30.1.1-android) and protobuf-1.0.0-M1.1.jar (org.nd4j:protobuf:1.0.0-M1.1)
Duplicate class com.google.thirdparty.publicsuffix.TrieParser found in modules guava-30.1.1-android.jar (com.google.guava:guava:30.1.1-android) and protobuf-1.0.0-M1.1.jar (org.nd4j:protobuf:1.0.0-M1.1)
Duplicate class javax.annotation.CheckForNull found in modules guava-1.0.0-M1.1.jar (org.nd4j:guava:1.0.0-M1.1) and jsr305-3.0.2.jar (com.google.code.findbugs:jsr305:3.0.2)
Duplicate class javax.annotation.CheckForSigned found in modules guava-1.0.0-M1.1.jar (org.nd4j:guava:1.0.0-M1.1) and jsr305-3.0.2.jar (com.google.code.findbugs:jsr305:3.0.2)
Duplicate class javax.annotation.CheckReturnValue found in modules guava-1.0.0-M1.1.jar (org.nd4j:guava:1.0.0-M1.1) and jsr305-3.0.2.jar (com.google.code.findbugs:jsr305:3.0.2)
Duplicate class javax.annotation.Detainted found in modules guava-1.0.0-M1.1.jar (org.nd4j:guava:1.0.0-M1.1) and jsr305-3.0.2.jar (com.google.code.findbugs:jsr305:3.0.2)
Duplicate class javax.annotation.MatchesPattern found in modules guava-1.0.0-M1.1.jar (org.nd4j:guava:1.0.0-M1.1) and jsr305-3.0.2.jar (com.google.code.findbugs:jsr305:3.0.2)
Duplicate class javax.annotation.MatchesPattern$Checker found in modules guava-1.0.0-M1.1.jar (org.nd4j:guava:1.0.0-M1.1) and jsr305-3.0.2.jar (com.google.code.findbugs:jsr305:3.0.2)
Duplicate class javax.annotation.Nonnegative found in modules guava-1.0.0-M1.1.jar (org.nd4j:guava:1.0.0-M1.1) and jsr305-3.0.2.jar (com.google.code.findbugs:jsr305:3.0.2)
Duplicate class javax.annotation.Nonnegative$Checker found in modules guava-1.0.0-M1.1.jar (org.nd4j:guava:1.0.0-M1.1) and jsr305-3.0.2.jar (com.google.code.findbugs:jsr305:3.0.2)
Duplicate class javax.annotation.Nonnull found in modules guava-1.0.0-M1.1.jar (org.nd4j:guava:1.0.0-M1.1) and jsr305-3.0.2.jar (com.google.code.findbugs:jsr305:3.0.2)
Duplicate class javax.annotation.Nonnull$Checker found in modules guava-1.0.0-M1.1.jar (org.nd4j:guava:1.0.0-M1.1) and jsr305-3.0.2.jar (com.google.code.findbugs:jsr305:3.0.2)
Duplicate class javax.annotation.Nullable found in modules guava-1.0.0-M1.1.jar (org.nd4j:guava:1.0.0-M1.1) and jsr305-3.0.2.jar (com.google.code.findbugs:jsr305:3.0.2)
Duplicate class javax.annotation.OverridingMethodsMustInvokeSuper found in modules guava-1.0.0-M1.1.jar (org.nd4j:guava:1.0.0-M1.1) and jsr305-3.0.2.jar (com.google.code.findbugs:jsr305:3.0.2)
Duplicate class javax.annotation.ParametersAreNonnullByDefault found in modules guava-1.0.0-M1.1.jar (org.nd4j:guava:1.0.0-M1.1) and jsr305-3.0.2.jar (com.google.code.findbugs:jsr305:3.0.2)
Duplicate class javax.annotation.ParametersAreNullableByDefault found in modules guava-1.0.0-M1.1.jar (org.nd4j:guava:1.0.0-M1.1) and jsr305-3.0.2.jar (com.google.code.findbugs:jsr305:3.0.2)
Duplicate class javax.annotation.PropertyKey found in modules guava-1.0.0-M1.1.jar (org.nd4j:guava:1.0.0-M1.1) and jsr305-3.0.2.jar (com.google.code.findbugs:jsr305:3.0.2)
Duplicate class javax.annotation.RegEx found in modules guava-1.0.0-M1.1.jar (org.nd4j:guava:1.0.0-M1.1) and jsr305-3.0.2.jar (com.google.code.findbugs:jsr305:3.0.2)
Duplicate class javax.annotation.RegEx$Checker found in modules guava-1.0.0-M1.1.jar (org.nd4j:guava:1.0.0-M1.1) and jsr305-3.0.2.jar (com.google.code.findbugs:jsr305:3.0.2)
Duplicate class javax.annotation.Signed found in modules guava-1.0.0-M1.1.jar (org.nd4j:guava:1.0.0-M1.1) and jsr305-3.0.2.jar (com.google.code.findbugs:jsr305:3.0.2)
Duplicate class javax.annotation.Syntax found in modules guava-1.0.0-M1.1.jar (org.nd4j:guava:1.0.0-M1.1) and jsr305-3.0.2.jar (com.google.code.findbugs:jsr305:3.0.2)
Duplicate class javax.annotation.Tainted found in modules guava-1.0.0-M1.1.jar (org.nd4j:guava:1.0.0-M1.1) and jsr305-3.0.2.jar (com.google.code.findbugs:jsr305:3.0.2)
Duplicate class javax.annotation.Untainted found in modules guava-1.0.0-M1.1.jar (org.nd4j:guava:1.0.0-M1.1) and jsr305-3.0.2.jar (com.google.code.findbugs:jsr305:3.0.2)
Duplicate class javax.annotation.WillClose found in modules guava-1.0.0-M1.1.jar (org.nd4j:guava:1.0.0-M1.1) and jsr305-3.0.2.jar (com.google.code.findbugs:jsr305:3.0.2)
Duplicate class javax.annotation.WillCloseWhenClosed found in modules guava-1.0.0-M1.1.jar (org.nd4j:guava:1.0.0-M1.1) and jsr305-3.0.2.jar (com.google.code.findbugs:jsr305:3.0.2)
Duplicate class javax.annotation.WillNotClose found in modules guava-1.0.0-M1.1.jar (org.nd4j:guava:1.0.0-M1.1) and jsr305-3.0.2.jar (com.google.code.findbugs:jsr305:3.0.2)
Duplicate class javax.annotation.concurrent.GuardedBy found in modules guava-1.0.0-M1.1.jar (org.nd4j:guava:1.0.0-M1.1) and jsr305-3.0.2.jar (com.google.code.findbugs:jsr305:3.0.2)
Duplicate class javax.annotation.concurrent.Immutable found in modules guava-1.0.0-M1.1.jar (org.nd4j:guava:1.0.0-M1.1) and jsr305-3.0.2.jar (com.google.code.findbugs:jsr305:3.0.2)
Duplicate class javax.annotation.concurrent.NotThreadSafe found in modules guava-1.0.0-M1.1.jar (org.nd4j:guava:1.0.0-M1.1) and jsr305-3.0.2.jar (com.google.code.findbugs:jsr305:3.0.2)
Duplicate class javax.annotation.concurrent.ThreadSafe found in modules guava-1.0.0-M1.1.jar (org.nd4j:guava:1.0.0-M1.1) and jsr305-3.0.2.jar (com.google.code.findbugs:jsr305:3.0.2)
Duplicate class javax.annotation.meta.Exclusive found in modules guava-1.0.0-M1.1.jar (org.nd4j:guava:1.0.0-M1.1) and jsr305-3.0.2.jar (com.google.code.findbugs:jsr305:3.0.2)
Duplicate class javax.annotation.meta.Exhaustive found in modules guava-1.0.0-M1.1.jar (org.nd4j:guava:1.0.0-M1.1) and jsr305-3.0.2.jar (com.google.code.findbugs:jsr305:3.0.2)
Duplicate class javax.annotation.meta.TypeQualifier found in modules guava-1.0.0-M1.1.jar (org.nd4j:guava:1.0.0-M1.1) and jsr305-3.0.2.jar (com.google.code.findbugs:jsr305:3.0.2)
Duplicate class javax.annotation.meta.TypeQualifierDefault found in modules guava-1.0.0-M1.1.jar (org.nd4j:guava:1.0.0-M1.1) and jsr305-3.0.2.jar (com.google.code.findbugs:jsr305:3.0.2)
Duplicate class javax.annotation.meta.TypeQualifierNickname found in modules guava-1.0.0-M1.1.jar (org.nd4j:guava:1.0.0-M1.1) and jsr305-3.0.2.jar (com.google.code.findbugs:jsr305:3.0.2)
Duplicate class javax.annotation.meta.TypeQualifierValidator found in modules guava-1.0.0-M1.1.jar (org.nd4j:guava:1.0.0-M1.1) and jsr305-3.0.2.jar (com.google.code.findbugs:jsr305:3.0.2)
Duplicate class javax.annotation.meta.When found in modules guava-1.0.0-M1.1.jar (org.nd4j:guava:1.0.0-M1.1) and jsr305-3.0.2.jar (com.google.code.findbugs:jsr305:3.0.2)

```

1. I tried to exclude conflicting modules:

```auto
    applicationVariants.all { variant ->
        variant.getRuntimeConfiguration().exclude group: 'com.google.code.findbugs', module: 'jsr305'
        variant.getRuntimeConfiguration().exclude group: 'org.nd4j', module: 'protobuf'
    }

```

But then in the runtime when the NN Learning starts, the app crashes with the exception:

```auto
java.lang.NoClassDefFoundError: Failed resolution of: Lorg/nd4j/shade/protobuf/ProtocolMessageEnum;
...
Caused by: java.lang.ClassNotFoundException: Didn't find class "org.nd4j.shade.protobuf.ProtocolMessageEnum"

```

1. Then I tried to _substitute_ conflicting modules:

```auto
configurations {
    all {
        resolutionStrategy.dependencySubstitution {
            substitute module('com.google.guava:guava:30.1.1-android') with module('org.nd4j:protobuf:1.0.0-M1.1')
            substitute module('com.google.code.findbugs:jsr305:3.0.2') with module('org.nd4j:guava:1.0.0-M1.1')
            substitute module('com.google.guava:guava:20.0') with module('org.nd4j:protobuf:1.0.0-M1.1')
        }
    }
}

```

It also caused the exception in the runtime:

```auto
java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/common/base/Preconditions;

```

1. Finally, I decided to try to use the same version of _grpc-_ libraries as _nd4j_ uses (1.14.0) but it also didn’t resolve conflict between these modules.

**3. Why do I think that it is the gRPC conflicting with ND4J?**  
The answer is simple - when I delete these dependencies the app builds without errors:

```auto
    implementation 'io.grpc:grpc-netty-shaded:1.44.1'
    implementation 'io.grpc:grpc-android:1.44.1'
    implementation 'io.grpc:grpc-protobuf-lite:1.44.1'
    implementation 'io.grpc:grpc-stub:1.44.1'

```

But removing them is not an option, because the _‘framework’_ module of our library needs these dependencies.

**4. Some other notes.**  
I suppose we need to use _1.0.0-M1.1_ version of _DL4J_ instead of _1.0.0-beta7_ because all attempts to run NN learning on _1.0.0-beta7_ ended with this exception:

```auto
E/Job: java.lang.ExceptionInInitializerError
    java.lang.ExceptionInInitializerError
        at org.nd4j.nativeblas.NativeOpsHolder.getInstance(NativeOpsHolder.java:119)
        at org.nd4j.linalg.cpu.nativecpu.ops.NativeOpExecutioner.<init>(NativeOpExecutioner.java:86)
        at java.lang.Class.newInstance(Native Method)
        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.<clinit>(Nd4j.java:270)
        at org.nd4j.linalg.factory.Nd4j.getRandom(Nd4j.java:493)
        at org.deeplearning4j.nn.conf.NeuralNetConfiguration$Builder.seed(NeuralNetConfiguration.java:579)
        at org.etu.fl.dl4j.nn.converters.DL4JNeuralNetConverter.createDL4JNetwork(DL4JNeuralNetConverter.java:215)
        at org.etu.fl.dl4j.nn.engines.NNInitializationEngine.learn(NNInitializationEngine.java:40)
        at org.etu.fl.core.algorithms.EnginedBlock.execute(EnginedBlock.java:89)
        at org.etu.fl.core.algorithms.AlgorithmBlock.run(AlgorithmBlock.java:63)
        at org.etu.fl.core.algorithms.SequenceBlock.execute(SequenceBlock.java:96)
        at org.etu.fl.core.algorithms.AlgorithmBlock.run(AlgorithmBlock.java:63)
        at org.etu.fl.client.worker.ProcessingWorker.call(ProcessingWorker.java:43)
        at org.etu.fl.client.worker.ProcessingWorker.call(ProcessingWorker.java:28)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:458)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:764)
     Caused by: java.lang.RuntimeException: ND4J is probably missing dependencies. For more information, please refer to: https://deeplearning4j.konduit.ai/nd4j/backend
        ...
     Caused by: java.lang.UnsatisfiedLinkError: dlopen failed: library "libc++_shared.so" not found
        ...

```

At the same time, the _1.0.0-M1.1_ version works fine.

**5. Sources and versions.**

- The _deeplearning_ module dependencies:

```auto
def dl4jVersion = '1.0.0-M1.1'
def openblasVersion = '0.3.10-1.5.5'
def opencvVersion = '4.5.1-1.5.5'
def leptonicaVersion = '1.80.0-1.5.5'

implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'com.google.android.material:material:1.5.0'

testImplementation 'junit:junit:4.13.2'

implementation project(path: ':fl4j-android-framework')

implementation(group: 'org.deeplearning4j', name: 'deeplearning4j-core', version: dl4jVersion) {
    exclude group: 'org.bytedeco', module: 'opencv-platform'
    exclude group: 'org.bytedeco', module: 'leptonica-platform'
    exclude group: 'org.bytedeco', module: 'hdf5-platform'
    exclude group: 'org.nd4j', module: 'nd4j-base64'
    exclude group: 'org.nd4j', module: 'nd4j-api'
}

implementation group: 'org.nd4j', name: 'nd4j-native', version: dl4jVersion
implementation group: 'org.nd4j', name: 'nd4j-native', version: dl4jVersion, classifier: "android-arm"
implementation group: 'org.nd4j', name: 'nd4j-native', version: dl4jVersion, classifier: "android-arm64"
implementation group: 'org.nd4j', name: 'nd4j-native', version: dl4jVersion, classifier: "android-x86"
implementation group: 'org.nd4j', name: 'nd4j-native', version: dl4jVersion, classifier: "android-x86_64"

implementation group: 'org.bytedeco', name: 'openblas', version: openblasVersion
implementation group: 'org.bytedeco', name: 'openblas', version: openblasVersion, classifier: "android-arm"
implementation group: 'org.bytedeco', name: 'openblas', version: openblasVersion, classifier: "android-arm64"
implementation group: 'org.bytedeco', name: 'openblas', version: openblasVersion, classifier: "android-x86"
implementation group: 'org.bytedeco', name: 'openblas', version: openblasVersion, classifier: "android-x86_64"

implementation group: 'org.bytedeco', name: 'opencv', version: opencvVersion
implementation group: 'org.bytedeco', name: 'opencv', version: opencvVersion, classifier: "android-arm"
implementation group: 'org.bytedeco', name: 'opencv', version: opencvVersion, classifier: "android-arm64"
implementation group: 'org.bytedeco', name: 'opencv', version: opencvVersion, classifier: "android-x86"
implementation group: 'org.bytedeco', name: 'opencv', version: opencvVersion, classifier: "android-x86_64"

implementation group: 'org.bytedeco', name: 'leptonica', version: leptonicaVersion
implementation group: 'org.bytedeco', name: 'leptonica', version: leptonicaVersion, classifier: "android-arm"
implementation group: 'org.bytedeco', name: 'leptonica', version: leptonicaVersion, classifier: "android-arm64"
implementation group: 'org.bytedeco', name: 'leptonica', version: leptonicaVersion, classifier: "android-x86"
implementation group: 'org.bytedeco', name: 'leptonica', version: leptonicaVersion, classifier: "android-x86_64"

annotationProcessor group: 'org.projectlombok', name: 'lombok', version: '1.18.4'

implementation "org.deeplearning4j:deeplearning4j-core:1.0.0-beta7"
implementation "org.nd4j:nd4j-native-platform:1.0.0-beta7"

androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'

```

- The _framework_ module dependencies:

```auto
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'com.google.android.material:material:1.5.0'

testImplementation 'junit:junit:4.13.2'

implementation 'io.grpc:grpc-netty-shaded:1.44.1'
implementation 'io.grpc:grpc-android:1.44.1'
implementation 'io.grpc:grpc-protobuf-lite:1.44.1'
implementation 'io.grpc:grpc-stub:1.44.1'

implementation 'net.javacrumbs.future-converter:future-converter-java8-guava:1.2.0'

compileOnly 'org.apache.tomcat:annotations-api:6.0.53'

implementation 'com.google.code.gson:gson:2.8.9'

implementation group: 'com.opencsv', name: 'opencsv', version: '5.2'
implementation group: 'org.postgresql', name: 'postgresql', version: '42.2.12'

androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'

```

- Android SDK versions:

```auto
compileSdkVersion 31
minSdkVersion 28
targetSdkVersion 30

```

- Android gradle plugin version: `com.android.tools.build:gradle:4.2.2`
- Gradle version: `gradle-6.8.1-bin`

---

<div class="post-metadata">

**Author:** ![agibsonccc](https://yyz1.discourse-cdn.com/flex035/user_avatar/community.konduit.ai/agibsonccc/32/697_2.png) [@agibsonccc](https://community.konduit.ai/u/agibsonccc)\
**Post date:** [March 24, 2022, 2:00am UTC](https://community.konduit.ai/t/android-nd4j-conflicts-with-grpc/1810/2 "2022-03-24T02:00:47Z")

</div>

@UnDan yes please use the updated versions. Can you clarify if this is still a problem with the newer versions?

---

<div class="post-metadata">

**Author:** ![UnDan](https://avatars.discourse-cdn.com/v4/letter/u/ac91a4/32.png) [@UnDan](https://community.konduit.ai/u/UnDan)\
**Post date:** [March 24, 2022, 11:43am UTC](https://community.konduit.ai/t/android-nd4j-conflicts-with-grpc/1810/3 "2022-03-24T11:43:18Z")

</div>

@agibsonccc yep, this issue remains on _1.0.0-M1.1_ version too.

---

<div class="post-metadata">

**Author:** ![UnDan](https://avatars.discourse-cdn.com/v4/letter/u/ac91a4/32.png) [@UnDan](https://community.konduit.ai/u/UnDan)\
**Post date:** [March 25, 2022, 10:40am UTC](https://community.konduit.ai/t/android-nd4j-conflicts-with-grpc/1810/4 "2022-03-25T10:40:25Z")

</div>

UPD:  
I forgot to mention that in addition to _gRPC_ dependencies there is one more dependency conflicting with _ND4J_:

```auto
implementation 'net.javacrumbs.future-converter:future-converter-java8-guava:1.2.0'

```

This dependency causes this:

```auto
Duplicate class com.google.common.util.concurrent.ListenableFuture found in modules guava-20.0.jar (com.google.guava:guava:20.0) and listenablefuture-1.0.jar (com.google.guava:listenablefuture:1.0)
Duplicate class com.google.thirdparty.publicsuffix.PublicSuffixPatterns found in modules guava-20.0.jar (com.google.guava:guava:20.0) and protobuf-1.0.0-M1.1.jar (org.nd4j:protobuf:1.0.0-M1.1)
Duplicate class com.google.thirdparty.publicsuffix.PublicSuffixType found in modules guava-20.0.jar (com.google.guava:guava:20.0) and protobuf-1.0.0-M1.1.jar (org.nd4j:protobuf:1.0.0-M1.1)
Duplicate class com.google.thirdparty.publicsuffix.TrieParser found in modules guava-20.0.jar (com.google.guava:guava:20.0) and protobuf-1.0.0-M1.1.jar (org.nd4j:protobuf:1.0.0-M1.1)

```
