Maven 2 & 3
  1. Maven 2 & 3
  2. MNG-2205

"provided" scope dependencies must be transitive

    Details

    • Type: Bug Bug
    • Status: Open Open
    • Priority: Critical Critical
    • Resolution: Unresolved
    • Affects Version/s: None
    • Fix Version/s: 3.x / Backlog
    • Component/s: Dependencies
    • Labels:
      None
    • Complexity:
      Intermediate
    • Number of attachments :
      1

      Description

      A provided scope dependency can also be thought of as "compile-only".

      Project A requires Sybase JConnect on the runtime classpath. Project A declares a "provided" dependency on Sybase JConnect.
      Project B depends upon Project A. Project B declares a "compile" dependency on Project A.
      Project C depends upon Project B. Project C declares a "compile" dependency on Project B.

      C
      | - compile dependency
      B
      | - compile dependency
      A
      | - provided dependency
      Sybase JConnect
      

      So, does Project C transitively depend on Sybase JConnect. Yes, of course! The "provided" dependency needs to be transitive.

      Ultimately, when Project C gets deployed, Sybase JConnect needs to be somewhere on the runtime classpath in order for the application to function. It's valid for Project C to assume that Sybase JConnect is available and use JDBC all over the Project C code. Project C is safe to do this because it can happily deduce that Sybase JConnect will be there in the runtime environment because Project A NEEDS IT.

      I've got Use Cases all over my aggregated build which make it absolutely critical and common sense that provided scope dependencies are transitive. For the (very rare) odd case where you don't want to inherit provided dependencies, you can <exclude/> them.

        Issue Links

          Activity

          Hide
          Tibor Digana added a comment - - edited

          I am using Maven 3.1.1
          This bug is very important and needs to be fixed.
          Especially in Java enterprise architecture the transitive scope of provided is used.
          You have inheritance of modules + parent in reactor:

          webapp module inherits(war) -> services(jar) -> dao(jar)

          So the DAO is dependent on Hibernate. The own Hibernate's dependencies (like. hibernate-jpa-2.0-api, ...) should be excluded, but the same javax artifacts should be included with the scope provided.
          The scope=provided on e.g. JPA API is necessary because we want to have own Hibernate's dependencie in compile time and tests as well. Additionally, the WAR file should NOT have libraries with javax packages in WEB-INF/lib.

          If you compile DAO module only, it succeeds.
          In reality you compile the parent POM in reactor, the build fails in module "services". The class from provided artifact was not inherited by the module "services". The webapp module wouldn't inherit it either.
          So the people make a workaround so that they put the same dependency with provided scope in module services or all modules.

          This is terrible because:
          + the inheritance in Maven is then useless
          + you duplicated the same dependencies with same scope
          + more work when maintaining the modules
          + the POM files are huge

          So the temporary workaround can be used to create parents Services-BOM and DAO-BOM with packaging=pom.
          Inheritance:
          Services-BOM -> DAO-BOM -> reactor's POM
          The DAO will have parent DAO-BOM with provided artifacts, and services will have parent Services-BOM.
          The problem with this impractical workaround is that you cannot use profiles otherwise you are on the beginning again.
          The Services-BOM and DAO-BOM have no noition of profiles in Maven 3.1.1.
          You need the profile bacause the build needs to be customized for different appication servers and anything else.

          Thx

          Show
          Tibor Digana added a comment - - edited I am using Maven 3.1.1 This bug is very important and needs to be fixed. Especially in Java enterprise architecture the transitive scope of provided is used. You have inheritance of modules + parent in reactor: webapp module inherits(war) -> services(jar) -> dao(jar) So the DAO is dependent on Hibernate. The own Hibernate's dependencies (like. hibernate-jpa-2.0-api, ...) should be excluded, but the same javax artifacts should be included with the scope provided. The scope=provided on e.g. JPA API is necessary because we want to have own Hibernate's dependencie in compile time and tests as well. Additionally, the WAR file should NOT have libraries with javax packages in WEB-INF/lib. If you compile DAO module only, it succeeds. In reality you compile the parent POM in reactor, the build fails in module "services". The class from provided artifact was not inherited by the module "services". The webapp module wouldn't inherit it either. So the people make a workaround so that they put the same dependency with provided scope in module services or all modules. This is terrible because: + the inheritance in Maven is then useless + you duplicated the same dependencies with same scope + more work when maintaining the modules + the POM files are huge So the temporary workaround can be used to create parents Services-BOM and DAO-BOM with packaging=pom. Inheritance: Services-BOM -> DAO-BOM -> reactor's POM The DAO will have parent DAO-BOM with provided artifacts, and services will have parent Services-BOM. The problem with this impractical workaround is that you cannot use profiles otherwise you are on the beginning again. The Services-BOM and DAO-BOM have no noition of profiles in Maven 3.1.1. You need the profile bacause the build needs to be customized for different appication servers and anything else. Thx
          Hide
          Tibor Digana added a comment - - edited

          I do not know if the bug is definitely in Maven core or maven-war-plugin 2.2 or 2.4.
          The efective-pom correctly resolves the modules DAO(jar) and Services(jar).
          For sure I will rollback to Maven 2.2.1 because there the profiles in DAO-BOM and Services-BOM work as expected.

          {code reactor's parent(pom) ^ +---------------------+ | ^ | | DAO(jar) -> DAO-BOM(pom) ^ ^ | | Services(jar) -> Services-BOM(pom) ^ | webapp(war)}

          The development profile has dependencies in DAO(jar):
          <groupId>org.hibernate</groupId>
          <artifactId>hibernate-core</artifactId>
          <version>4.2.6.Final</version>

          Th production profile has dependencies in DAO(jar):
          <dependency>
          <groupId>org.hibernate</groupId>
          <artifactId>hibernate-core</artifactId>
          <version>4.2.6.Final</version>
          <exclusions>
          <exclusion>
          <groupId>org.jboss.spec.javax.transaction</groupId>
          <artifactId>jboss-transaction-api_1.1_spec</artifactId>
          </exclusion>
          </exclusions>
          </dependency>
          <dependency>
          <groupId>org.jboss.spec.javax.transaction</groupId>
          <artifactId>jboss-transaction-api_1.1_spec</artifactId>
          <version>1.0.1.Final</version>
          <scope>provided</scope>
          </dependency>

          Show
          Tibor Digana added a comment - - edited I do not know if the bug is definitely in Maven core or maven-war-plugin 2.2 or 2.4. The efective-pom correctly resolves the modules DAO(jar) and Services(jar). For sure I will rollback to Maven 2.2.1 because there the profiles in DAO-BOM and Services-BOM work as expected. {code reactor's parent(pom) ^ +---------------------+ | ^ | | DAO(jar) -> DAO-BOM(pom) ^ ^ | | Services(jar) -> Services-BOM(pom) ^ | webapp(war)} The development profile has dependencies in DAO(jar): <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>4.2.6.Final</version> Th production profile has dependencies in DAO(jar): <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>4.2.6.Final</version> <exclusions> <exclusion> <groupId>org.jboss.spec.javax.transaction</groupId> <artifactId>jboss-transaction-api_1.1_spec</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.jboss.spec.javax.transaction</groupId> <artifactId>jboss-transaction-api_1.1_spec</artifactId> <version>1.0.1.Final</version> <scope>provided</scope> </dependency>
          Hide
          Jason van Zyl added a comment -

          It is unlikely we will change the behavior of the provided scope, but it would be possible to create a new 'provided-transitive' if we really wanted this. Changing the definition of existing scopes would be problematic.

          Show
          Jason van Zyl added a comment - It is unlikely we will change the behavior of the provided scope, but it would be possible to create a new 'provided-transitive' if we really wanted this. Changing the definition of existing scopes would be problematic.
          Hide
          Tibor Digana added a comment -

          @Jason
          The problem is that the behavior has changed after Maven 2.2.1.
          New keywords would not be acceptable by the community in my guess - this may take quite long time to implement and finally the Maven users may get lost.
          I prefer simplicity and correct behavior against huge number of keywords.
          The right solution would be to concentrate on fixing hunderds of bugs in the Maven project. First of all to write tests against Maven 2 behavior and then run the same tests on Maven 3, let's see what will happen.

          Show
          Tibor Digana added a comment - @Jason The problem is that the behavior has changed after Maven 2.2.1. New keywords would not be acceptable by the community in my guess - this may take quite long time to implement and finally the Maven users may get lost. I prefer simplicity and correct behavior against huge number of keywords. The right solution would be to concentrate on fixing hunderds of bugs in the Maven project. First of all to write tests against Maven 2 behavior and then run the same tests on Maven 3, let's see what will happen.
          Hide
          Jason van Zyl added a comment -

          I would love it if you concentrated fixing the hundreds of bugs in Maven. Our attempt is in our integrations tests of which there are hundreds which do exactly that: capture behaviour across Maven versions:

          https://github.com/apache/maven-integration-testing

          Feel free to augment. Also make sure that what you're asking for is actually happening in the core and is not a function of a particular plugin which does its own resolution. The WAR plugin for example.

          Look forward to your patches.

          Show
          Jason van Zyl added a comment - I would love it if you concentrated fixing the hundreds of bugs in Maven. Our attempt is in our integrations tests of which there are hundreds which do exactly that: capture behaviour across Maven versions: https://github.com/apache/maven-integration-testing Feel free to augment. Also make sure that what you're asking for is actually happening in the core and is not a function of a particular plugin which does its own resolution. The WAR plugin for example. Look forward to your patches.

            People

            • Assignee:
              Unassigned
              Reporter:
              David Boden
            • Votes:
              61 Vote for this issue
              Watchers:
              66 Start watching this issue

              Dates

              • Created:
                Updated: