Skip to main content

Command Palette

Search for a command to run...

Tuning gradle variant compatibility

Updated
3 min read

A real-life case how to force gradle accepting dependency with higer java version requirement.

My animalsniffer gradle plugin targets java 8 (keeps minimum compatiblity):

java {
    sourceCompatibility = 1.8
}

Now, in order to add android support, I want to add an optional dependency for android plugin:

dependencies {
    compileOnly 'com.android.tools.build:gradle:8.4.0'
}

But, this will not work:

> Could not resolve all files for configuration ':compileClasspath'.
   > Could not resolve com.android.tools.build:gradle:8.4.0.
     Required by:
         project :
      > No matching variant of com.android.tools.build:gradle:8.4.0 was found. The consumer was configured to find a library for use during compile-time, compatible with Java 8, preferably not packaged as a jar, preferably optimized for standard JVMs, and its dependencies declared externally, as well as attribute 'org.gradle.plugin.api-version' with value '8.6' but:
          - Variant 'apiElements' capability com.android.tools.build:gradle:8.4.0 declares a library for use during compile-time, packaged as a jar, preferably optimized for standard JVMs, and its dependencies declared externally:
              - Incompatible because this component declares a component, compatible with Java 11 and the consumer needed a component, compatible with Java 8
              - Other compatible attribute:
                  - Doesn't say anything about org.gradle.plugin.api-version (required '8.6')
          - Variant 'javadocElements' capability com.android.tools.build:gradle:8.4.0 declares a component for use during runtime, and its dependencies declared externally:
              - Incompatible because this component declares documentation and the consumer needed a library
              - Other compatible attributes:
                  - Doesn't say anything about its target Java environment (preferred optimized for standard JVMs)
                  - Doesn't say anything about its target Java version (required compatibility with Java 8)
                  - Doesn't say anything about its elements (required them preferably not packaged as a jar)
                  - Doesn't say anything about org.gradle.plugin.api-version (required '8.6')
          - Variant 'runtimeElements' capability com.android.tools.build:gradle:8.4.0 declares a library for use during runtime, packaged as a jar, preferably optimized for standard JVMs, and its dependencies declared externally:
              - Incompatible because this component declares a component, compatible with Java 11 and the consumer needed a component, compatible with Java 8
              - Other compatible attribute:
                  - Doesn't say anything about org.gradle.plugin.api-version (required '8.6')
          - Variant 'sourcesElements' capability com.android.tools.build:gradle:8.4.0 declares a component for use during runtime, and its dependencies declared externally:
              - Incompatible because this component declares documentation and the consumer needed a library
              - Other compatible attributes:
                  - Doesn't say anything about its target Java environment (preferred optimized for standard JVMs)
                  - Doesn't say anything about its target Java version (required compatibility with Java 8)
                  - Doesn't say anything about its elements (required them preferably not packaged as a jar)
                  - Doesn't say anything about org.gradle.plugin.api-version (required '8.6')

The main problem:

Incompatible because this component declares a component, compatible with Java 11 and the consumer needed a component, compatible with Java 8

No matter what JDK I actually use for this build (17), gradle complains that dependency is not compatible with declared targetCompatibility\=1.8 (not a mistake, by default targetCompatibility == sourceCompatibility)

But, I assume this dependency to be an optional: android project would use java 11 (17) in any case, but my plugin should also work for pure java projects under java 8.

To workaround this moment, I have to manually declare (override) target jvm attribute for configuration (in build.gradle):

import org.gradle.api.attributes.java.TargetJvmVersion

configurations.compileClasspath.attributes
    .attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 11)

And now java 8 target does not cause problem anymore.

Helpful links:

  1. Gradle attributes doc

  2. Attributes definition example

More from this blog

Vyacheslav Rusakov's Blog

20 posts