Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gradle ignores transitive dependencies of configuration provided when retrieved from artifacts pom.xml

My java based project is built using gradle. The build script has a compile dependency on a jar.

dependencies {
  compile 'com.group:artificat:1.2.3'
}

in the artifact repository exists the following pom.xml for artifact-1.2.3.jar

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.group</groupId>
    <artifactId>artifact</artifactId>
    <version>1.2.3</version>
    <dependencies>
        <dependency>
          <groupId>org.jboss.spec.javax.ejb</groupId>
          <artifactId>jboss-ejb-api_3.1_spec</artifactId>
          <version>1.0.2.Final-redhat-3</version>
          <scope>provided</scope>
        </dependency>
        <dependency>
          <groupId>org.jboss.spec.javax.servlet</groupId>
          <artifactId>jboss-servlet-api_3.0_spec</artifactId>
          <version>1.0.2.Final-redhat-2</version>
          <scope>provided</scope>
        </dependency>
    </dependencies>
</project>

Those jars in provided configuration are needed for my project to compile but gradle ignores them when compiling the code, thus failing the build.

This doesn't happen when dependencies are not transitive.

As a workaround I've added those dependencies "hard coded"

dependencies {
 provided 'org.jboss.spec.javax.ejb:jboss-ejb-api_3.1_spec:1.0.2.Final-redhat-3'
 provided 'org.jboss.spec.javax.servlet:jboss-servlet-api_3.0_spec:1.0.2.Final-redhat-2'
}

Is there a better solution to this problem?

like image 644
Aviv Bronshtein Avatar asked Sep 13 '25 19:09

Aviv Bronshtein


1 Answers

According to the Maven POM reference, provided dependencies are not transitive:

provided - this is much like compile, but indicates you expect the JDK or a container to provide it at runtime. It is only available on the compilation and test classpath, and is not transitive.

You should definitely declare those dependencies explicitly (as you have done).

As a rule of thumb, if your application won't compile without an artifact then that artifact should be listed as an explicit dependency.

Otherwise you've get in trouble when that transitive dependency is no longer included in the build. Consider:

  1. X depends on Y.
  2. You declare an dependency on X.
  3. You use classes from Y.
  4. You upgrade to a new version of X which no longer depends on Y.
  5. Since you don't have an explicit dependency on Y, your build breaks.
like image 198
dnault Avatar answered Sep 16 '25 08:09

dnault