Return-Path: Delivered-To: apmail-maven-commits-archive@www.apache.org Received: (qmail 30782 invoked from network); 7 Feb 2006 01:56:07 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 7 Feb 2006 01:56:07 -0000 Received: (qmail 57732 invoked by uid 500); 7 Feb 2006 01:56:06 -0000 Delivered-To: apmail-maven-commits-archive@maven.apache.org Received: (qmail 57694 invoked by uid 500); 7 Feb 2006 01:56:06 -0000 Mailing-List: contact commits-help@maven.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@maven.apache.org Delivered-To: mailing list commits@maven.apache.org Received: (qmail 57683 invoked by uid 99); 7 Feb 2006 01:56:06 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 06 Feb 2006 17:56:06 -0800 X-ASF-Spam-Status: No, hits=-9.4 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.29) with SMTP; Mon, 06 Feb 2006 17:56:05 -0800 Received: (qmail 30669 invoked by uid 65534); 7 Feb 2006 01:55:45 -0000 Message-ID: <20060207015545.30663.qmail@minotaur.apache.org> Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r375444 - /maven/site/trunk/src/site/apt/guides/introduction/introduction-to-optional-and-excludes-dependencies.apt Date: Tue, 07 Feb 2006 01:55:44 -0000 To: commits@maven.apache.org From: aramirez@apache.org X-Mailer: svnmailer-1.0.6 X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Author: aramirez Date: Mon Feb 6 17:55:43 2006 New Revision: 375444 URL: http://svn.apache.org/viewcvs?rev=375444&view=rev Log: -added intro to optional and excludes dependencies Added: maven/site/trunk/src/site/apt/guides/introduction/introduction-to-optional-and-excludes-dependencies.apt Added: maven/site/trunk/src/site/apt/guides/introduction/introduction-to-optional-and-excludes-dependencies.apt URL: http://svn.apache.org/viewcvs/maven/site/trunk/src/site/apt/guides/introduction/introduction-to-optional-and-excludes-dependencies.apt?rev=375444&view=auto ============================================================================== --- maven/site/trunk/src/site/apt/guides/introduction/introduction-to-optional-and-excludes-dependencies.apt (added) +++ maven/site/trunk/src/site/apt/guides/introduction/introduction-to-optional-and-excludes-dependencies.apt Mon Feb 6 17:55:43 2006 @@ -0,0 +1,307 @@ + ------ + Optional Dependencies and Dependency Exclusions + ------ + Allan Ramirez + ------ + 23 January 2006 + ------ + +~~ Copyright 2001-2005 The Apache Software Foundation. +~~ +~~ Licensed under the Apache License, Version 2.0 (the "License"); +~~ you may not use this file except in compliance with the License. +~~ You may obtain a copy of the License at +~~ +~~ http://www.apache.org/licenses/LICENSE-2.0 +~~ +~~ Unless required by applicable law or agreed to in writing, software +~~ distributed under the License is distributed on an "AS IS" BASIS, +~~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +~~ See the License for the specific language governing permissions and +~~ limitations under the License. + +Introduction + + This section discusses the functionality of optional dependencies and + dependency exclusions. This will help users to understand what are they, + how to use them, how they work and when is the best way to use them. + It also explains why exclusions are made as per dependency basis not in + a POM level. + +* Optional Dependencies + + Optional dependencies are used when it's not really possible + (for whatever reason) to split a project up into sub-modules. + The idea is that some of the dependencies are only used for certain features + in the project, and will not be needed if that feature isn't used. Ideally, + such a feature would be split into a sub-module that depended on the core + functionality project...this new subproject would have only non-optional + dependencies, since you'd need them all if you decided to use the + subproject's functionality. + + However, since the project cannot be split up (again, for whatever reason), + these dependencies are declared optional. If a user wants to use + functionality related to an optional dependency, they will have to redeclare + that optional dependency in their own project. This is not the most clear + way to handle this situation, but then again both optional dependencies and + dependency exclusions are stop-gap solutions. + +** Why use optional dependencies? + + It's not only important to declare optional dependencies in order to save + space/memory/etc. It's vital to control the list of actual dependencies a + person needs in order to use a project, since these jars may eventually make + it into a WAR, EAR, EJB, etc. Inclusion of the wrong jars may violate a + license agreement, cause classpath issues, etc. + +** How do I use the optional tag? + + A dependency is declared as optional by simply setting the \ tag + to true in your dependency declaration. See the sample below: + ++---+ + + + ... + + + + sample.ProjectA + Project-A + 1.0 + compile + true + + + + ++---+ + +** How do optional dependencies work? + ++---+ + +Project-A -> Project-B + ++---+ + + The diagram above says that Project-A depends on Project-B. When A + declares B as an optional dependency in its POM, this relationship remains + unchanged. Its just like a normal build where Project-B will be added in its + classpath. + ++---+ + +Project-X -> Project-A + ++---+ + + But when another project(Project-X) declares Project-A as a dependency in + its POM, the optional dependency takes effect. You'll notice that + Project-B is not included in the classpath of Project-X; you will + need to declare it directly in your POM in order for B to be included + in X's classpath. + +** Example + + Let us say that there is a project named that has similar functions + with which supports many database drivers/dependencies such as + mysql, postgre, oracle etc. All of these dependencies are needed for X2 + to build but not for your project, so it is very practical for X2 to + declare these dependencies as optional, so that whenever your project + declares X2 as a direct dependency in your POM, all the drivers supported + by the X2 will not be automatically included to your project's classpath + instead you'll have to declare it directly on what driver/dependency of the + database you are going to use. + +* Dependency Exclusions + + Since maven 2.x resolves dependencies transitively, it is possible + for unwanted dependencies to be included in your project's classpath. + Projects that you depend on may not have declared their set of dependencies + correctly, for example. In order to address this special situtation, + maven 2.x has incorporated the notion of explicit dependency exclusion. + Exclusions are set on a specific dependency in your POM, and are targeted + at a specific groupId and artifactId. When you build your project, that + artifact will not be added to your project's classpath . + +** How to use dependency exclusions + + We add the \ tag under the \ section of the pom. + ++---+ + + + ... + + + sample.ProjectA + Project-A + 1.0 + compile + + + sample.ProjectB + Project-B + + + + + + ++---+ + +** How dependency exclusion works and when to use it <<( as a last resort! )>> + ++---+ + +Project-A + -> Project-B + -> Project-D + -> Project-E + -> Project-F + -> Project C + ++---+ + + The diagram shows that Project-A depends on both Project-B and C. Project-B + depends on Project-D. Project-D depends on both Project-E and F. By default, + Project A's classpath will include: + ++---+ +B, C, D, E, F ++---+ + + What if we dont want project D and its dependencies to be added to + Project A's classpath because we know some of Project-D's dependencies + (maybe Project-E for example) was missing from the repository, and you + don't need/want the functionality in Project-B that depends on Project-D + anyway. In this case, Project-B's developers could provide a dependency on + Project-D that is \true\, like this: + ++---+ + + sample.ProjectD + ProjectD + 1.0-SNAPSHOT + true + ++---+ + + HOWEVER, they didn't. As a last resort, you still have the option to exclude it + on your side, in Project-A, like this: + ++---+ + + + 4.0.0 + sample.ProjectA + Project-A + 1.0-SNAPSHOT + jar + ... + + + sample.ProjectB + Project-B + 1.0-SNAPSHOT + + + sample.ProjectD + Project-D + + + + + + ++---+ + + If we deploy the Project-A to a repository, and Project-X declares a + normal dependency on Project-A, will Project-D be excluded from the + classpath still? + ++---+ + +Project-X -> Project-A + ++---+ + + The answer is <>. Project-A has declared that it doesn't need + Project-D to run, so it won't be brought in as a transitive dependency + of Project-A. + + Now, consider that Project-X depends on Project-Y, as in the diagram below: + ++---+ + +Project-X -> Project-Y + -> Project-B + -> Project-D + ... + ++---+ + + Project-Y also has a dependency on Project-B, and it does need the features + supported by Project-D. Therefore, it will NOT place an exclusion on + Project-D in its dependency list. It may also supply an additional + repository, from which we can resolve Project-E. In this case, it's important + that Project-D <> excluded globally, since it is a legitimate + dependency of Project-Y. + + As another scenario, what if the dependency we don't want is Project-E + instead of Project-D. How will we exclude it? See the diagram below: + ++---+ + +Project-A + -> Project-B + -> Project-D + -> Project-E + -> Project-F + -> Project C + ++---+ + + Exclusions work on the entire dependency graph below the point where they + are declared. If you wanted to exclude Project-E instead of Project-D, + you'd simply change the exclusion to point at Project-E, but you wouldn't + move the exclusion down to Project-D...you cannot change Project-D's POM. + If you could, you would use optional dependencies instead of exclusions, + or split Project-D up into multiple subprojects, each with nothing but + normal dependencies. + ++---+ + + + 4.0.0 + sample.ProjectA + Project-A + 1.0-SNAPSHOT + jar + ... + + + sample.ProjectB + Project-B + 1.0-SNAPSHOT + + + sample.ProjectE + Project-E + + + + + + ++---+ + +** Why exclusions are made on a per-dependency basis, rather than at the POM level + + This is mainly done to be sure the dependency graph is predictable, and to + keep inheritance effects from excluding a dependency that should not be + excluded. If you get to the method of last resort and have to put in an + exclusion, you should be absolutely certain which of your dependencies is + bringing in that unwanted transitive dependency.