2

Migrated to Kotlin .kts and now I'm getting some build issues.

These are some of the errors:

> Could not resolve all files for configuration ':app:stagingNewDesignDebugRuntimeClasspath'.
   > Could not resolve com.pierfrancescosoffritti.androidyoutubeplayer:core:10.0.5.
     Required by:
         project :app
      > Could not resolve com.pierfrancescosoffritti.androidyoutubeplayer:core:10.0.5.
         > Could not get resource 'https://nexus.central.tech/repository/nexus-releases/com/pierfrancescosoffritti/androidyoutubeplayer/core/10.0.5/core-10.0.5.pom'.
            > Could not HEAD 'https://nexus.central.tech/repository/nexus-releases/com/pierfrancescosoffritti/androidyoutubeplayer/core/10.0.5/core-10.0.5.pom'. Received status code 401 from server: Unauthorized
      > Could not resolve com.pierfrancescosoffritti.androidyoutubeplayer:core:10.0.5.
         > Could not get resource 'https://s3.amazonaws.com/salesforcesos.com/android/maven/release/com/pierfrancescosoffritti/androidyoutubeplayer/core/10.0.5/core-10.0.5.pom'.

What I don't understand is that the dependency being appended to our Nexus server.

Could not resolve com.pierfrancescosoffritti.androidyoutubeplayer:core:10.0.5.
         > Could not get resource 'https://nexus.central.tech/repository/nexus-releases/com/pierfrancescosoffritti/androidyoutubeplayer/core/10.0.5/core-10.0.5.pom

Our Nexus repository is https://nexus.central.tech/repository/nexus-releases But /com/pierfrancescosoffritti/androidyoutubeplayer/core/10.0.5/core-10.0.5.pom keeps getting appended to it. And that is why it can't find the full path and the build will fail.

androidyoutubeplayer doesn't come from our Nexus so I don't understand why it's trying to get it from there.

// build.gradle.kts

repositories {
      google()
      mavenCentral()
      maven {
          url = uri(properties["nexusRepositoryUrl"].toString())
  
          credentials {
              username = properties["nexusRepositoryUsername"].toString()
              username = properties["nexusRepositoryPassword"].toString()
          }
      }
        
      maven { url = uri("https://www.jitpack.io") }
      maven { url = uri("https://s3.amazonaws.com/salesforcesos.com/android/maven/release") }
      maven { url = uri("https://dl.bintray.com/objectbox/objectbox") }
      maven { url = uri("https://sdk.uxcam.com/android/") }
}

UPDATE -- after correcting the username/password

Could not determine the dependencies of task ':app:compileUatDebugKotlin'.
> Could not resolve all files for configuration ':app:stagingNewDesignDebugRuntimeClasspath'.
   > Could not resolve com.pierfrancescosoffritti.androidyoutubeplayer:core:10.0.5.
     Required by:
         project :app
      > Skipped due to earlier error
      > Could not resolve com.pierfrancescosoffritti.androidyoutubeplayer:core:10.0.5.
         > Could not get resource 'https://s3.amazonaws.com/salesforcesos.com/android/maven/release/com/pierfrancescosoffritti/androidyoutubeplayer/core/10.0.5/core-10.0.5.pom'.
            > Could not HEAD 'https://s3.amazonaws.com/salesforcesos.com/android/maven/release/com/pierfrancescosoffritti/androidyoutubeplayer/core/10.0.5/core-10.0.5.pom'. Received status code 403 from server: Forbidden

After looking at the git repo for androidyoutubeplayer. It should fetch that dependency from mavenCentral(). So Not sure why its looking at the above.

=== UPDATE 2 === jcenter() was removed originally, but I have put it back as we have some libraries that are old from there that haven't found their way to mavenCentral(). That was why some of the dependencies could not be found. So it was continue to search the other repositories.

This is build.gradle.kts

repositories {
    google()
    jcenter()
    mavenCentral()
    maven {
        url = uri(properties["nexusRepositoryUrl"].toString())

        credentials {
            username = properties["nexusRepositoryUsername"].toString()
            password = properties["nexusRepositoryPassword"].toString()

            /* TODO: Remove after debugging */
            println("USERNAME: $username")
            println("PASSWORD: $password")
            println("URL: $url")
        }
    }

    maven { url = uri("https://sdk.uxcam.com/android/") }
    maven { url = uri("https://www.jitpack.io") }
    maven { url = uri("https://s3.amazonaws.com/salesforcesos.com/android/maven/release") }
    maven { url = uri("https://dl.bintray.com/objectbox/objectbox") }
}

And this is the build.gradle (working ok)

repositories {
    google()
    jcenter()
    mavenCentral()
    maven {
        url nexusRepositoryUrl

        credentials {
            username nexusRepositoryUsername
            password nexusRepositoryPassword
        }
    }
    maven { url 'https://sdk.uxcam.com/android/'}
    maven { url "https://www.jitpack.io" }
    maven { url 'https://s3.amazonaws.com/salesforcesos.com/android/maven/release' }
    maven { url "https://dl.bintray.com/objectbox/objectbox" }
}

The errors are different now. This is what I get when building:

.gradle/caches/transforms-2/files-2.1/8fc5090e854d3eadc13743a6b4942213/jetified-kotlin-stdlib-1.6.0.jar!/META-INF/kotlin-stdlib.kotlin_module: Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.6.0, expected version is 1.4.2.


.gradle/caches/transforms-2/files-2.1/bdaa895e8cd4dd25cc3b271fb1f2fc8e/jetified-kotlin-stdlib-jdk7-1.6.0.jar!/META-INF/kotlin-stdlib-jdk7.kotlin_module: Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.6.0, expected version is 1.4.2.

.gradle/caches/transforms-2/files-2.1/cebf6956c831e2c0ba58bc90c4d45ce7/jetified-kotlin-stdlib-common-1.6.0.jar!/META-INF/kotlin-stdlib-common.kotlin_module: Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.6.0, expected version is 1.4.2.

.gradle/caches/transforms-2/files-2.1/e0c09723c14595670dad4b40acbe2360/jetified-core-11.0.1-api.jar!/META-INF/core_release.kotlin_module: Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.6.0, expected version is 1.4.2.

.gradle/caches/transforms-2/files-2.1/ec9cde959f0fd7b7d9fe2427414ce447/jetified-kotlin-stdlib-jdk8-1.6.0.jar!/META-INF/kotlin-stdlib-jdk8.kotlin_module: Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.6.0, expected version is 1.4.2.

This is my project level build.gradle.kts

buildscript {
    val kotlin_version = "1.4.32"
    val navigationVersion = "2.3.5"
    val objectboxVersion = "2.9.1"
    val jacocoVersion = "0.8.5"
    val sonarVersion = "3.0"
    val newRelicVersion = "5.28.1"

    repositories {
        google()
        mavenCentral()
    }

    dependencies {
        classpath("com.android.tools.build:gradle:4.2.2")
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:")
        classpath("org.jetbrains.kotlin:kotlin-noarg:$kotlin_version")
        classpath("org.jacoco:org.jacoco.core:$jacocoVersion")
        classpath("org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:$sonarVersion")
        classpath("androidx.navigation:navigation-safe-args-gradle-plugin:$navigationVersion")
        classpath("com.google.gms:google-services:4.3.8")
        classpath("com.google.firebase:perf-plugin:1.3.4")
        classpath("com.google.firebase:firebase-appdistribution-gradle:2.0.1")
        classpath("com.google.firebase:firebase-crashlytics-gradle:2.4.1")
        classpath("io.objectbox:objectbox-gradle-plugin:$objectboxVersion")
        classpath("com.newrelic.agent.android:agent-gradle-plugin:$newRelicVersion")
        classpath("com.akaita.android:easylauncher:1.3.1")

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

What I don't understand the build.gradle before migration works fine and all the versions of kotlin and dependencies are the same. As I have it on another branch.

When running the following command ./gradlew assembleUat --info

Failed to get resource: GET. [HTTP HTTP/1.1 403 Forbidden: https://s3.amazonaws.com/salesforcesos.com/android/maven/release/com/google/firebase/firebase-messaging/maven-metadata.xml)]
Failed to get resource: GET. [HTTP HTTP/1.1 502 Bad Gateway: https://dl.bintray.com/objectbox/objectbox/com/google/firebase/firebase-messaging/maven-metadata.xml)]
Failed to get resource: GET. [HTTP HTTP/1.1 502 Bad Gateway: https://dl.bintray.com/objectbox/objectbox/com/google/firebase/firebase-messaging/maven-metadata.xml)]
Failed to get resource: GET. [HTTP HTTP/1.1 502 Bad Gateway: https://dl.bintray.com/objectbox/objectbox/com/google/firebase/firebase-messaging/maven-metadata.xml)]
Failed to get resource: GET. [HTTP HTTP/1.1 403 Forbidden: https://s3.amazonaws.com/salesforcesos.com/android/maven/release/com/google/android/gms/play-services-location/maven-metadata.xml)]
Failed to get resource: GET. [HTTP HTTP/1.1 403 Forbidden: https://s3.amazonaws.com/salesforcesos.com/android/maven/release/com/google/android/gms/play-services-ads-identifier/maven-metadata.xml)]
Failed to get resource: GET. [HTTP HTTP/1.1 403 Forbidden: https://s3.amazonaws.com/salesforcesos.com/android/maven/release/com/google/android/gms/play-services-base/maven-metadata.xml)]
Failed to get resource: GET. [HTTP HTTP/1.1 403 Forbidden: https://s3.amazonaws.com/salesforcesos.com/android/maven/release/com/akamai/android/aka-common/maven-metadata.xml)]
ant2009
  • 27,094
  • 154
  • 411
  • 609
  • Can you provide the original `build.gradle` that you're converting from? I suspect that the new error regarding `androidyoutubeplayer` is because Maven Central [doesn't have the version you're requesting](https://search.maven.org/artifact/com.pierfrancescosoffritti.androidyoutubeplayer/core). [It exists on JitPack](https://jitpack.io/#PierfrancescoSoffritti/android-youtube-player/10.0.5), but I think `uri("https://www.jitpack.io")` is wrong - try `uri("https://jitpack.io")` – aSemy Jul 11 '22 at 10:31
  • "It should fetch that dependency from mavenCentral(). So Not sure why its looking at the above" Gradle will try all repositories to find the artifacts, unless you add a content filter. I suspect that `https://s3.amazonaws.com/salesforcesos.com` is being unconventional and is returning 403 instead of 404. When Gradle can't find the artifact, it guesses that 403 is a problem, rather than assuming the artifact doesn't exist. – aSemy Jul 11 '22 at 10:36
  • 1
    Looking at [the docs](https://developer.salesforce.com/docs/atlas.en-us.service_sdk_android.meta/service_sdk_android/android_install_sdk.htm) it seems you can add `content { includeGroup("com.salesforce.service") }` to the Salesforce Maven repo. Then Gradle will only search for Salesforce artifacts in that repo. This will also improve performance, as Gradle won't bother searching that repo for unrelated artifacts. – aSemy Jul 11 '22 at 10:36
  • The problem of `androidyoutubeplayer` has been resolved. The dependency for that version was in `jcenter` so I have added that back. – ant2009 Jul 11 '22 at 16:07
  • Thanks. What version of Gradle are you using? Is it the same as before you migrated to `.kts`? Can you try deleting the contents of `~/.gradle/caches/` and trying again? Though I think you should open a new question - it seems the original problem has been solved and this is unrelated? I'm also confused because you've shared two `build.gradle.kts` files - both are different, and have different repositories. – aSemy Jul 11 '22 at 17:26
  • @aSemy You was correct in one of your comments. Using the includegroup was the answer. I have given a complete answer to this question. With reference to your comment. – ant2009 Jul 13 '22 at 14:14

2 Answers2

3

The Gradle errors when it can't locate files in repositories are often confusing. What is important though is it says

Received status code 401 from server: Unauthorized.

Gradle doesn't know what artifact is stored in which repository, so it searches all of them for the .pom definition - but it fails because the username and password are incorrect.

I suspect that if you add some debug log statements, you'll see something unexpected.

// build.gradle.kts

credentials {
  username = properties["nexusRepositoryUsername"].toString()

  username = properties["nexusRepositoryPassword"].toString()
  // ^^^                                   ^^^

  println("repo user: $username")
  println("repo pass: $password")
}

Of course, don't commit those to your repo!

Improvements

Aside from fixing the username/password mix-up, you can do more things to help out.

  1. Use repository content filtering to tell Gradle what artifacts are stored in which repository.

    Find the groups of the dependencies that you need to filter (I looked at the Salesforce docs to find them), and then configure the filtering in Gradle:

    // build.gradle.kts
    
    repositories {
      maven {
        url = uri(properties["nexusRepositoryUrl"].toString())
        content {
          // this repository *only* contains artifacts with the specified groups
          includeGroup("com.salesforce.service")
          includeGroup("com.salesforce.android")
        }
      }
    
       // also filter 'objectbox' dependencies
       maven("https://dl.bintray.com/objectbox/objectbox") {
         content {
           includeGroup("io.objectbox")
         }
      }
    }
    

    Now Gradle will only search for Salesforce artifacts in that repo. As a nice side-effect, This will also improve performance, as Gradle won't bother searching that repo for unrelated artifacts.

  2. Use 'named repository credentials' to automatically set the username/password based on the repository name.

    See the answer here for a more thorough explanation of named repository credentials

    // build.gradle.kts
    
    repositories {
      maven {
        url = uri(properties["nexusRepositoryUrl"].toString())
        name = "nexusRepository"
        credentials(PasswordCredentials::class)
      }
    }
    
    # $GRADLE_USER_HOME/gradle.properties
    nexusRepositoryUsername=my-username
    nexusRepositoryPassword=my-password
    
aSemy
  • 5,485
  • 2
  • 25
  • 51
  • I have correct the username and password. As I had set the username twice. However, the problem still persists. – ant2009 Jul 10 '22 at 13:19
  • Before with the incorrect username/password I was getting 401 unauthorized. But with the correct username/password I am getting the following: `status code 403 from server: Forbidden` – ant2009 Jul 10 '22 at 13:29
  • Please update your question to include more of Gradle error. Do other projects have the problem? Are you able to access the repository in your web browser if you navigate to `https://nexus.central.tech/repository/nexus-releases/` and enter the user/pass you've set in Gradle? – aSemy Jul 10 '22 at 14:27
  • I can login into the nexus with username and password. I have 2 branches. One is the original before migrating to kotlin KTS (still working ok). And the other branch has the errors after the migration. I have updated my question with the error message – ant2009 Jul 10 '22 at 14:42
-1

The solution was based on @aSemy comment. Which was to include only the dependencies that are needed for those repositories.

  maven {
        url = uri("https://s3.amazonaws.com/salesforcesos.com/android/maven/release")
        content {
            includeGroup("com.salesforce.service")
            includeGroup("com.salesforce.android")
        }
    }

    maven {
        url = uri("https://dl.bintray.com/objectbox/objectbox")

        content {
            includeGroup("io.objectbox")
        }
    }
ant2009
  • 27,094
  • 154
  • 411
  • 609