How to download transitive dependency?

In one project which, is using maven, I have this in pom.xml:

<dependency>
    <groupId>com.nixxcode.jvmbrotli</groupId>
    <artifactId>jvmbrotli</artifactId>
    <version>0.2.0</version>
    <optional>true</optional>
</dependency>

With that, maven will also download (according to platform):
com.nixxcode.jvmbrotli.jvmbrotli-linux-x86-amd64:0.2.0

In another project, which is using gradle I have in build.gradle:

compileOnly ('com.nixxcode.jvmbrotli:jvmbrotli:0.2.0') {
    transient = true //As far as I know this is the default
}

Although it is not downloading the linux-86-amd64 package. I have to include it manually to make it work:

compileOnly 'com.nixxcode.jvmbrotli:jvmbrotli-linux-x86-amd64:0.2.0'

What do I have to do to make it work automatically as I have no control on which platform will be later compiled?

@lepe

Take a look at the pom file for your dependency. The transitive dependency uses maven profiles to pull in the OS specific jar.

Gradle does not have full support of maven profile activation. See this old blog on how Gradle deals with consuming Maven dependencies that rely on profiles. Gradle can support:

  1. Profiles that are active by default.
  2. Profiles that are active on the absence of a system property.

Unfortunately, the library you are pulling uses OS activation. I suspect that is the reason. I’m not aware of a workaround other than manually adding the transitive dependency.

You can use if conditions to add the correct dependency based on the os.name and os.arch system properties. See example.

Thanks!

Thank you so much for your explanation! Now it is clear to me… :slight_smile:
I think the example you included will be useful. Thanks again.

One note regarding the example, I would rather do it like

when {
    Os.isFamily(FAMILY_WINDOWS) -> ...
    Os.isFamily(FAMILY_MAC) -> ...
    Os.isFamily(FAMILY_UNIX) -> ...
    else -> throw ConfigurationException("Unsupported OS family")
}

where Os is org.apache.tools.ant.taskdefs.condition.Os which is a first-class citizen in Gradle.

1 Like

Thank you!

This is what i finally did:

import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform

dependencies {
    def os = DefaultNativePlatform.currentOperatingSystem
    def arch = DefaultNativePlatform.currentArchitecture

    def jvmbrotli = "0.2.0"
    api "com.nixxcode.jvmbrotli:jvmbrotli:$jvmbrotli"

    switch (true) {
        case os.windows && arch.i386:
            api "com.nixxcode.jvmbrotli:jvmbrotli-win32-x86:$jvmbrotli"
            break
        case os.windows && arch.amd64:
            api "com.nixxcode.jvmbrotli:jvmbrotli-win32-x86-amd64:$jvmbrotli"
            break
        case os.macOsX && arch.amd64:
            api "com.nixxcode.jvmbrotli:jvmbrotli-darwin-x86-amd64:$jvmbrotli"
            break
        case os.linux && arch.amd64:
            api "com.nixxcode.jvmbrotli:jvmbrotli-linux-x86-amd64:$jvmbrotli"
            break
        default:
            println "No suitable driver of Brotli found for current " +
                "OS (${os.displayName}) and architecture (${arch.displayName}). "
    }
}

Well, that means you are using Gradle internal classes which can break anytime, even with a minor version increase. I’d strongly suggest you use the Ant class instead. :wink: