Gradle ignores transitive dependencies when specifying a classifier

I am working on a multi platform Java EE product/framework project. We need to support different ApplicationServer platforms, like JBoss, WebSphere, Glassfish,… We are currently working with a Maven build and use classifiers to distinguish the different platforms. Now I’d like to evaluate Gradle to check whether we could do the same build using Gradle, but I run into the following problem:

When specifying a dependency with classifier, e.g.

compile ‘mygroup:mymodule:1.0-SNAPSHOT:glassfish4’

Gradle ignores transitive dependencies - in contrast to Maven.

If I rename the JAR of the artifact in my local Maven cache from mymodule-1.0-SNAPSHOT-glassfish4.jar to mymodule-1.0-SNAPSHOT.jar transitive dependencies are resolved as expected.

Is this a bug or am I missing something regarding dependency management in Gradle?

Sounds like a bug to me. Can you also reproduce this when resolving from a remote repository, rather than Maven Local?

I don’t know an open source project on maven central that uses classifiers this way.

Here is a small reproducer.

pom.xml of MyModule:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <groupId>mygroup</groupId>
 <artifactId>mymodule</artifactId>
 <version>1.0-SNAPSHOT</version>
   <packaging>jar</packaging>
   <dependencies>
  <dependency>
   <groupId>org.apache.commons</groupId>
   <artifactId>commons-lang3</artifactId>
   <version>3.3.2</version>
  </dependency>
 </dependencies>
      <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-jar-plugin</artifactId>
                    <version>2.5</version>
                    <executions>
                        <execution>
                            <id>default-jar</id>
                            <goals>
                                <goal>jar</goal>
                            </goals>
                            <configuration>
                                <classifier>${platform}</classifier>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
  </project>

Build MyModule using:

mvn install -Dplatform=glassfish4

build.gradle of MyProject looks like this:

apply plugin: 'java'
  group = 'mygroup'
version = '1.0-SNAPSHOT'
  repositories {
    mavenLocal()
    mavenCentral()
}
  dependencies {
    compile 'mygroup:mymodule:1.0-SNAPSHOT:glassfish4'
}

Calling gradle dependencies only lists mygroup:mymodule:1.0-SNAPSHOT After renaming mymodule-1.0-SNAPSHOT-glassfish4.jar to mymodule-1.0-SNAPSHOT.jar in the local maven cache commons-lang3 will be listed as transitive dependency.

I don’t know an open source project on maven central that uses classifiers this way.

Are you saying that there is anything special about your usage of classifiers?

It would be great to know if the problem is limited to Maven Local or also applies to remote repositories (i.e. the standard case; Maven Local should only be used if artifacts need to be exchanged with a local Maven build).

We just do not only use the common classifiers tests or sources. We also use classifiers to distinguish application server specific jars. The jars can contain platform specific classes (security, transaction management,…), platform specific deployment descriptors or generated EJB classes. As far as I know, this is not disallowed by maven:

“The classifier allows to distinguish artifacts that were built from the same POM but differ in their content. It is some optional and arbitrary string that - if present - is appended to the artifact name just after the version number.” (http://maven.apache.org/pom.html)

Another use case would be to distinguish native libraries by os or chip architecture identifier.

I just don’ t know a project on Maven Central that uses such classifiers.

That sounds like regular use of classifiers. One big limitation of classifiers is that you can’t have a separate POM per classifier, which in particular means that you can’t have separate (e.g. platform specific) dependencies.

Anyhow, I’ve created GRADLE-3188 to look further into this. Thanks for the report.

We don’t use classifier specific dependencies. If necessary, platform specific dependencies are defined by a platform specific artifact.

Thanks & Regards, Ralf

I remembered that transitive dependencies with classifiers used to work with Gradle some time ago when I was first experimenting with Gradle. So I tried my scenario above with different versions of Gradle wrapper:

Transitive dependencies were working up to Gradle 1.10. After Gradle 1.11 this is broken.

Have you tried with 2.1 and 2.2-rc-1?

2.1 and 2.2-rc-1 do not work either.

Thanks for investigating.