Apollo-android: Publish library that uses apollo-android internally

Created on 26 Jun 2020  路  17Comments  路  Source: apollographql/apollo-android

Question.
I want to upgrade apollo-android in our in-house libary to 2.1.0+ but have problems with the new multi-platform changes for the cache module.
We publish our library to our internal repository and use that in Apps. But when using apollo-normalized-cache-sqlite in 2.1.0 our apps fail to build because the cannot resolve the cache module.
Do we need to setup multi-platform publishing for our internal library (that only support Android) because apollo now uses multi-platform? If not, how do we get it to build again?

The error message is like this:

   > Could not resolve com.apollographql.apollo:apollo-normalized-cache-sqlite:2.1.0.
     Required by:
         project :app > com.example:internal-library:1.2.3-SNAPSHOT
      > Cannot choose between the following variants of com.apollographql.apollo:apollo-normalized-cache-sqlite:2.1.0:
          - android-debugApiElements
          - android-debugRuntimeElements
          - jvm-api
          - jvm-runtime
        All of them match the consumer attributes:
          - Variant 'android-debugApiElements' capability com.apollographql.apollo:apollo-normalized-cache-sqlite:2.1.0:
              - Unmatched attributes:
                  - Found com.android.build.api.attributes.VariantAttr 'debug' but wasn't required.
                  - Found com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Aar' but wasn't required.
                  - Found org.gradle.status 'release' but wasn't required.
                  - Found org.jetbrains.kotlin.platform.type 'androidJvm' but wasn't required.
              - Compatible attributes:
                  - Required com.android.build.api.attributes.BuildTypeAttr 'debug' and found compatible value 'debug'.
                  - Required org.gradle.usage 'java-api' and found compatible value 'java-api'.
          - Variant 'android-debugRuntimeElements' capability com.apollographql.apollo:apollo-normalized-cache-sqlite:2.1.0:
              - Unmatched attributes:
                  - Found com.android.build.api.attributes.VariantAttr 'debug' but wasn't required.
                  - Found com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Aar' but wasn't required.
                  - Found org.gradle.status 'release' but wasn't required.
                  - Found org.jetbrains.kotlin.platform.type 'androidJvm' but wasn't required.
              - Compatible attributes:
                  - Required com.android.build.api.attributes.BuildTypeAttr 'debug' and found compatible value 'debug'.
                  - Required org.gradle.usage 'java-api' and found compatible value 'java-runtime'.
          - Variant 'jvm-api' capability com.apollographql.apollo:apollo-normalized-cache-sqlite:2.1.0:
              - Unmatched attributes:
                  - Required com.android.build.api.attributes.BuildTypeAttr 'debug' but no value provided.
                  - Found org.gradle.libraryelements 'jar' but wasn't required.
                  - Found org.gradle.status 'release' but wasn't required.
                  - Found org.jetbrains.kotlin.platform.type 'jvm' but wasn't required.
              - Compatible attribute:
                  - Required org.gradle.usage 'java-api' and found compatible value 'java-api'.
          - Variant 'jvm-runtime' capability com.apollographql.apollo:apollo-normalized-cache-sqlite:2.1.0:
              - Unmatched attributes:
                  - Required com.android.build.api.attributes.BuildTypeAttr 'debug' but no value provided.
                  - Found org.gradle.libraryelements 'jar' but wasn't required.
                  - Found org.gradle.status 'release' but wasn't required.
                  - Found org.jetbrains.kotlin.platform.type 'jvm' but wasn't required.
              - Compatible attribute:
                  - Required org.gradle.usage 'java-api' and found compatible value 'java-runtime'.
Question

All 17 comments

You can take a look at similar problems in https://github.com/apollographql/apollo-android/issues/2357 and #2253 . What's happening is that multiplatform publishes several variants of a given module and Gradle will have to lookup the correct one based on what the consumer is asking for.

Usually, the Kotlin and Android plugins do the right thing and configure attributes correctly but if you have some custom logic it might be that you have to explicit some constraints. Above the log you pasted, you should see a line saying Could not resolve all files for configuration ':someConfiguration'. If you take that someConfiguration, you can ask for JVM explicitely with code like this:

configurations.named("someConfiguration").configure {
    attributes {
        attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.JAVA_RUNTIME))
    }
}

HTH, let me know if it worked

Just to clarify: Our library uses kotlin internally but the apps only apply the standard android plugin. No kotlin dependency in the build setup. I'll try with the above code to see if it works for us.

I'M not having success with the above code, it looks like it can't find the configuration?!

Here is an updated erorr without the code snippen above:

Could not determine the dependencies of task ':app:lintRelease'.
 > Could not resolve all artifacts for configuration ':app:debugCompileClasspath'.
    > Could not resolve com.apollographql.apollo:apollo-normalized-cache-sqlite:2.2.0.
      Required by:
          project :app
       > The consumer was configured to find an API of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug'. However we cannot choose between the following variants of com.apollographql.apollo:apollo-normalized-cache-sqlite:2.2.0:
           - android-debugApiElements
           - android-debugRuntimeElements
           - jvm-api
           - jvm-runtime
         All of them match the consumer attributes:
           - Variant 'android-debugApiElements' capability com.apollographql.apollo:apollo-normalized-cache-sqlite:2.2.0 declares an API of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug':
               - Unmatched attributes:
                   - Provides attribute 'com.android.build.api.attributes.VariantAttr' with value 'debug' but the consumer didn't ask for it
                   - Provides attribute 'com.android.build.gradle.internal.dependency.AndroidTypeAttr' with value 'Aar' but the consumer didn't ask for it
                   - Provides release status but the consumer didn't ask for it
                   - Provides attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm' but the consumer didn't ask for it
           - Variant 'android-debugRuntimeElements' capability com.apollographql.apollo:apollo-normalized-cache-sqlite:2.2.0 declares a runtime of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug':
               - Unmatched attributes:
                   - Provides attribute 'com.android.build.api.attributes.VariantAttr' with value 'debug' but the consumer didn't ask for it
                   - Provides attribute 'com.android.build.gradle.internal.dependency.AndroidTypeAttr' with value 'Aar' but the consumer didn't ask for it
                   - Provides release status but the consumer didn't ask for it
                   - Provides attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm' but the consumer didn't ask for it
           - Variant 'jvm-api' capability com.apollographql.apollo:apollo-normalized-cache-sqlite:2.2.0 declares an API of a component:
               - Unmatched attributes:
                   - Doesn't say anything about com.android.build.api.attributes.BuildTypeAttr (required 'debug')
                   - Provides its elements packaged as a jar but the consumer didn't ask for it
                   - Provides release status but the consumer didn't ask for it
                   - Provides attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm' but the consumer didn't ask for it
           - Variant 'jvm-runtime' capability com.apollographql.apollo:apollo-normalized-cache-sqlite:2.2.0 declares a runtime of a component:
               - Unmatched attributes:
                   - Doesn't say anything about com.android.build.api.attributes.BuildTypeAttr (required 'debug')
                   - Provides its elements packaged as a jar but the consumer didn't ask for it
                   - Provides release status but the consumer didn't ask for it
                   - Provides attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm' but the consumer didn't ask for it
         The following variants were also considered but didn't match the requested attributes:
           - Variant 'android-releaseApiElements' capability com.apollographql.apollo:apollo-normalized-cache-sqlite:2.2.0 declares an API of a component:
               - Incompatible because this component declares a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'release' and the consumer needed a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug'
           - Variant 'android-releaseRuntimeElements' capability com.apollographql.apollo:apollo-normalized-cache-sqlite:2.2.0 declares a runtime of a component:
               - Incompatible because this component declares a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'release' and the consumer needed a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug'
           - Variant 'ios-api' capability com.apollographql.apollo:apollo-normalized-cache-sqlite:2.2.0:
               - Incompatible because this component declares a usage of 'kotlin-api' of a component and the consumer needed an API of a component
               - Other compatible attribute:
                   - Doesn't say anything about com.android.build.api.attributes.BuildTypeAttr (required 'debug')
           - Variant 'iosSim-api' capability com.apollographql.apollo:apollo-normalized-cache-sqlite:2.2.0:
               - Incompatible because this component declares a usage of 'kotlin-api' of a component and the consumer needed an API of a component
               - Other compatible attribute:
                   - Doesn't say anything about com.android.build.api.attributes.BuildTypeAttr (required 'debug')
           - Variant 'metadata-api' capability com.apollographql.apollo:apollo-normalized-cache-sqlite:2.2.0:
               - Incompatible because this component declares a usage of 'kotlin-api' of a component and the consumer needed an API of a component
               - Other compatible attribute:
                   - Doesn't say anything about com.android.build.api.attributes.BuildTypeAttr (required 'debug')
    > Could not resolve com.apollographql.apollo:apollo-normalized-cache-sqlite:2.2.0.
      Required by:
          project :app > com.example:internal-library:1.2.3-SNAPSHOT
       > The consumer was configured to find an API of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug'. However we cannot choose between the following variants of com.apollographql.apollo:apollo-normalized-cache-sqlite:2.2.0:
           - android-debugApiElements
           - android-debugRuntimeElements
           - jvm-api
           - jvm-runtime
         All of them match the consumer attributes:
           - Variant 'android-debugApiElements' capability com.apollographql.apollo:apollo-normalized-cache-sqlite:2.2.0 declares an API of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug':
               - Unmatched attributes:
                   - Provides attribute 'com.android.build.api.attributes.VariantAttr' with value 'debug' but the consumer didn't ask for it
                   - Provides attribute 'com.android.build.gradle.internal.dependency.AndroidTypeAttr' with value 'Aar' but the consumer didn't ask for it
                   - Provides release status but the consumer didn't ask for it
                   - Provides attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm' but the consumer didn't ask for it
           - Variant 'android-debugRuntimeElements' capability com.apollographql.apollo:apollo-normalized-cache-sqlite:2.2.0 declares a runtime of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug':
               - Unmatched attributes:
                   - Provides attribute 'com.android.build.api.attributes.VariantAttr' with value 'debug' but the consumer didn't ask for it
                   - Provides attribute 'com.android.build.gradle.internal.dependency.AndroidTypeAttr' with value 'Aar' but the consumer didn't ask for it
                   - Provides release status but the consumer didn't ask for it
                   - Provides attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm' but the consumer didn't ask for it
           - Variant 'jvm-api' capability com.apollographql.apollo:apollo-normalized-cache-sqlite:2.2.0 declares an API of a component:
               - Unmatched attributes:
                   - Doesn't say anything about com.android.build.api.attributes.BuildTypeAttr (required 'debug')
                   - Provides its elements packaged as a jar but the consumer didn't ask for it
                   - Provides release status but the consumer didn't ask for it
                   - Provides attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm' but the consumer didn't ask for it
           - Variant 'jvm-runtime' capability com.apollographql.apollo:apollo-normalized-cache-sqlite:2.2.0 declares a runtime of a component:
               - Unmatched attributes:
                   - Doesn't say anything about com.android.build.api.attributes.BuildTypeAttr (required 'debug')
                   - Provides its elements packaged as a jar but the consumer didn't ask for it
                   - Provides release status but the consumer didn't ask for it
                   - Provides attribute 'org.jetbrains.kotlin.platform.type' with value 'jvm' but the consumer didn't ask for it
         The following variants were also considered but didn't match the requested attributes:
           - Variant 'android-releaseApiElements' capability com.apollographql.apollo:apollo-normalized-cache-sqlite:2.2.0 declares an API of a component:
               - Incompatible because this component declares a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'release' and the consumer needed a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug'
           - Variant 'android-releaseRuntimeElements' capability com.apollographql.apollo:apollo-normalized-cache-sqlite:2.2.0 declares a runtime of a component:
               - Incompatible because this component declares a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'release' and the consumer needed a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug'
           - Variant 'ios-api' capability com.apollographql.apollo:apollo-normalized-cache-sqlite:2.2.0:
               - Incompatible because this component declares a usage of 'kotlin-api' of a component and the consumer needed an API of a component
               - Other compatible attribute:
                   - Doesn't say anything about com.android.build.api.attributes.BuildTypeAttr (required 'debug')
           - Variant 'iosSim-api' capability com.apollographql.apollo:apollo-normalized-cache-sqlite:2.2.0:
               - Incompatible because this component declares a usage of 'kotlin-api' of a component and the consumer needed an API of a component
               - Other compatible attribute:
                   - Doesn't say anything about com.android.build.api.attributes.BuildTypeAttr (required 'debug')
           - Variant 'metadata-api' capability com.apollographql.apollo:apollo-normalized-cache-sqlite:2.2.0:
               - Incompatible because this component declares a usage of 'kotlin-api' of a component and the consumer needed an API of a component
               - Other compatible attribute:
                   - Doesn't say anything about com.android.build.api.attributes.BuildTypeAttr (required 'debug')

I looks like it tries to resolve a debug variant for lintRelease but apollo-normalized-cache-sqlite is only available as release. Not sure why

Gradle actually finds too many possible variants:

However we cannot choose between the following variants of com.apollographql.apollo:apollo-normalized-cache-sqlite:2.2.0:
           - android-debugApiElements
           - android-debugRuntimeElements
           - jvm-api
           - jvm-runtime

Given the below:

           - Variant 'jvm-runtime' capability com.apollographql.apollo:apollo-normalized-cache-sqlite:2.2.0 declares a runtime of a component:
               - Unmatched attributes:
                   - Doesn't say anything about com.android.build.api.attributes.BuildTypeAttr (required 'debug')

I would expect jvm-runtime (and respectively jvm-api) to be discarded but that is somehow not the case.

As a workaround for now, can you try adding apollo-normalized-cache-sqlite-android as a dependency instead of apollo-normalized-cache-sqlite?

Actually tried that just now, this is the result:

Could not determine the dependencies of task ':app:lintDebug'.
 > Could not resolve all artifacts for configuration ':app:debugCompileClasspath'.
    > Could not resolve com.apollographql.apollo:apollo-normalized-cache-sqlite-android:2.2.1.
      Required by:
          project :app > com.example:internal-library:1.2.3-SNAPSHOT
       > No matching variant of com.apollographql.apollo:apollo-normalized-cache-sqlite-android:2.2.1 was found. The consumer was configured to find an API of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug', attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm' but:
           - Variant 'android-releaseApiElements' capability com.apollographql.apollo:apollo-normalized-cache-sqlite-android:2.2.1 declares an API of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm':
               - Incompatible because this component declares a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'release' and the consumer needed a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug'
           - Variant 'android-releaseRuntimeElements' capability com.apollographql.apollo:apollo-normalized-cache-sqlite-android:2.2.1 declares a runtime of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm':
               - Incompatible because this component declares a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'release' and the consumer needed a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug'
           - Variant 'metadata-api' capability com.apollographql.apollo:apollo-normalized-cache-sqlite-android:2.2.1:
               - Incompatible because this component declares a usage of 'kotlin-api' of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'common' and the consumer needed an API of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm'
               - Other compatible attribute:
                   - Doesn't say anything about com.android.build.api.attributes.BuildTypeAttr (required 'debug')

same for lintRelease

Could not determine the dependencies of task ':app:lintRelease'.
 > Could not resolve all artifacts for configuration ':app:debugCompileClasspath'.
    > Could not resolve com.apollographql.apollo:apollo-normalized-cache-sqlite-android:2.2.1.
      Required by:
          project :app > com.example:internal-library:1.2.3-SNAPSHOT
       > No matching variant of com.apollographql.apollo:apollo-normalized-cache-sqlite-android:2.2.1 was found. The consumer was configured to find an API of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug', attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm' but:
           - Variant 'android-releaseApiElements' capability com.apollographql.apollo:apollo-normalized-cache-sqlite-android:2.2.1 declares an API of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm':
               - Incompatible because this component declares a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'release' and the consumer needed a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug'
           - Variant 'android-releaseRuntimeElements' capability com.apollographql.apollo:apollo-normalized-cache-sqlite-android:2.2.1 declares a runtime of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm':
               - Incompatible because this component declares a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'release' and the consumer needed a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'debug'
           - Variant 'metadata-api' capability com.apollographql.apollo:apollo-normalized-cache-sqlite-android:2.2.1:
               - Incompatible because this component declares a usage of 'kotlin-api' of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'common' and the consumer needed an API of a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'androidJvm'
               - Other compatible attribute:
                   - Doesn't say anything about com.android.build.api.attributes.BuildTypeAttr (required 'debug')

So it looks like the app's build requests a debug variant but only get's release version.

I only configure the two standard build types:

buildTypes {
    debug {
        debuggable true
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        signingConfig signingConfigs.release
    }
}

Huh, I seem to have found a "solution":

buildTypes {
    debug {
        debuggable true
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        matchingFallbacks = ["release", "debug"]
    }
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        signingConfig signingConfigs.release
        matchingFallbacks = ["release", "debug"]
    }
}

Interesting, if I leave the matchingFallbacks in and switch back to com.apollographql.apollo:apollo-normalized-cache-sqlite it now fails with:

Could not determine the dependencies of task ':app:lintDebug'.
 > Could not resolve all artifacts for configuration ':app:debugCompileClasspath'.
    > Could not find apollo-normalized-cache-sqlite-2.2.1.aar (com.apollographql.apollo:apollo-normalized-cache-sqlite:2.2.1).
      Searched in the following locations:
          https://nexus.example.com/repository/maven-public/com/apollographql/apollo/apollo-normalized-cache-sqlite/2.2.1/apollo-normalized-cache-sqlite-2.2.1.aar

Final working config for me is:

  • Use implementation "com.apollographql.apollo:apollo-normalized-cache-sqlite-android:$apolloVersion"
  • Use matchingFallbacks = ["release"] for both debug and release buildTypes

Ah, nope. Now the test app inside our internal library is not working / gradle fails with
Unable to resolve dependency for ':internal-library@debug/compileClasspath': Could not resolve com.apollographql.apollo:apollo-normalized-cache-sqlite-android:2.2.1.
inside Android Studio :/

Damn! May I ask how you publish internal-library? Do you use the maven-publish plugin or something else? Can you share the resulting .module file? (for an example, the apollo-normalized-cache-sqlite is there)

Also it might be worth bumping the Gradle version if you're not on 6.5 already. 6.4+ has some improvements around variant resolution. Using 6.5 should not harm.

We're on 6.5 and use maven-publish BUT we do not have any .module being published. Could that be the reason? I'm not sure how to enable publishing the module file. I'll take a look

I also just noticed, our maven-publish setup pre-dates support from the Android plugin (https://developer.android.com/studio/build/maven-publish-plugin). I'll adjust to the new way and re-test.

we do not have any .module being published. Could that be the reason? I'm not sure how to enable publishing the module file. I'll take a look

I was under the impression that .module files where published by default starting with Gradle 6.0. Unless maybe it's disabled?

We did not explicitly disable it.

I've updated the publish setup and now I'm getting .module files and now the app build works.
Thank you @martinbonnin - that was the hint I needed :-)

For reference:

  • matchingFallbacks is not needed
  • I'm using the apollo-normalized-cache-sqlite dependency again

Nice, glad it's working, thanks for the investigation :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

john-lanticse picture john-lanticse  路  3Comments

mmahesh2019 picture mmahesh2019  路  4Comments

pratthama-appdesk picture pratthama-appdesk  路  3Comments

AOrobator picture AOrobator  路  3Comments

TayfunCesur picture TayfunCesur  路  4Comments