kotlin:S1874 False positives on some List methods with Java 21

SonarQube sometimes reports deprecation warnings (kotlin:S1874) for List methods that aren’t deprecated.

  • Kotlin’s List<T>.first() extension method.
  • Java’s List.removeLast() method.

This happened immediately after I upgraded the project’s JVM toolchain from Java 17 to 21. The methods aren’t deprecated in Java 21.

Weirdly, not all occurrences of these method calls are being reported. F.e. myGenericList.first() got reported, but myString.split('-', limit = 2).first() didn’t. (Where myGenericListhas the type List<T> with T : Any.)

  • SonarQube: 9.9.2 (not sure about the deployment type)
  • Gradle Plugin: 4.4.1.3373
  • Gradle: 8.5
  • Kotlin: 1.9.21
  • Java: 21

Hi Georg!

I can’t reproduce your problem. Neither of both examples triggers S1874 for me. I’m using the same toolchain version as you, except for SonarQube 9.9.3 (but I don’t think that makes the difference). Maybe can you provide me with some more information? (i.e., your build script and a minimal source file in which the problem occurs).

This is my minimal setup in which I couldn’t observe the described effect:

Main.kt:

// Unused import to get at least one report in SQ
import java.awt.ActiveEvent;

fun <T: Any>foo(myGenericList: List<T>): T {
    return myGenericList.first()
}

fun bar(myString: String): String {
    return myString.split('-', limit = 2).first();
}

build.gradle.kts:

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    kotlin("jvm") version "1.9.21"
    id("org.sonarqube") version "4.4.1.3373"
}

group = "org.example"
version = "1.0-SNAPSHOT"

repositories {
    mavenCentral()
}

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(21)
    }
}

tasks.withType<KotlinCompile> {
    kotlinOptions.jvmTarget = "21"
}

Best,
Marco

Hi Marco,

I’ve directly copied your minimal setup into a fresh, empty project. The issue also appears there. (In foo. bar isn’t affected.) The only other files in the project are gradle.properties with the Sonar URL and project key, settings.gradle.kts with the root project name, and the Gradle Wrapper files.

We’ve also updated SonarQube to version 9.9.3, but that didn’t change anything.

(The analysis warning in the screenshot is just because the test project has no SCM provider.)

In case it’s relevant: I’m using the Java 21.0.1 distribution from Temurin.

Please let me know if I can provide more information.

This is strange. Maybe could you provide me also with the gradle.properties and settings.gradle.kts? These and Temurin should now be the only three differences between my and your setup. I’ll try these too and then get back to you.

I’m just asking for completeness to rule out any other causes for this behavior: you are using the Gradle wrapper when doing the analysis, i.e., ./gradlew, not gradle , right?

Yes, I’m using ./gradlew sonar with the Gradle Wrapper 8.5.

settings.gradle.kts

rootProject.name = "sonar-kotlin-s1874"

gradle.properties

# SonarScanner configuration.
systemProp.sonar.projectKey=test-sonar-kotlin-s1874
systemProp.sonar.host.url=https://(internal url)

I’ve tested a bit more. The issue appears when I execute ./gradlew using Java 21, but not when I execute it using Java 17. The configured toolchain doesn’t matter.

I.e. I can change 21 to 17 in build.gradle.kts and the issue still appears. But if I change my shell’s default Java version to 17 (using SDKMAN!'s sdk use java 17.0.9-tem), the issue disappears, even if the Gradle Java toolchain still uses Java 21.

I’ve also tried a different vendor (sdk use java 21.0.1-zulu), but the issue still appears.

1 Like

I think this is related to the fact that Kotlin analyzer doesn’t consider your “compile-time” Java version and takes the runtime one.

There’s a ticket to take a proper Java version into account here:

https://sonarsource.atlassian.net/browse/SONARKT-270

Note: the deprecation rule in Kotlin is based on the Compiler warning, so this means that the rule itself should work correctly but there might indeed be misconfiguration.

Let’s wait till the ticket is fixed, and then get back to us if the issue is still there.

Best,
Margarita

2 Likes