Ivy
  1. Ivy
  2. IVY-1309

Exclude dosn't work in a more complex build enviroment

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.1.0
    • Fix Version/s: 2.3.0-RC1
    • Component/s: Core
    • Labels:
      None

      Description

      We are using ant 1.8.2 and Ivy 2.1.0 for our build. When resolving an ivy file the module wide exclude fails to stop a matching transitive dependency from coming in. I have reduced the build down as much as possible to try and make it easy to diagnose but if I strip any more out then the problem goes away. I don't believe there is anything wrong with what's there, it's from a very mature system used to build all the Springsource projects internally. I will upload a zip to reproduce.

      1. Unzip the zip file.
      2. At the command line go in to the unzipped, 'kernel' directory.
      3. run 'ant clean package'
      4. in the target directory just created there will be a 'org.eclipse.osgi-3.7.0.v20110613' file, this is excluded in the ivy file.

      The ivy and build files are pretty minimal but I can't see anything I've done wrong. The artifacts it's pulling in are in the ivy-cache/integration-repo directories so nothing needs to be downloaded.

      Chris.

      1. kernel.zip
        3.63 MB
        Christopher Frost

        Activity

        Hide
        Nicolas Lalevée added a comment -

        Thanks for the pointer Luke and the test case Christopher. It was some circular dependency which bypassed the full check on the exclusion pattern.

        Show
        Nicolas Lalevée added a comment - Thanks for the pointer Luke and the test case Christopher. It was some circular dependency which bypassed the full check on the exclusion pattern.
        Hide
        Luke Renn added a comment -

        I'm able to fix this issue by making IvyNodeCallers not check the full callers list if it finds the exclusions in the module descriptor. In this case, equinox get re-included when the kernel.userreqion caller is checked (since it's a dependency there). I've got a fix locally, but I'm pretty sure that will break dependency level excludes that really should get reincluded.

        The relevant code is:

        IvyCallers.java
            boolean doesCallersExclude(String rootModuleConf, Artifact artifact, Stack callersStack) {
                if (callersStack.contains(node.getId())) {
                    return false;
                }
                callersStack.push(node.getId());
                try {
                    Caller[] callers = getCallers(rootModuleConf);
                    if (callers.length == 0) {
                        return false;
                    }
        
                    for (int i = 0; i < callers.length; i++) {
        
                        if (!callers[i].canExclude()) {
                            return false;
                        }
        
                        if (!doesExclude(md, rootModuleConf, callers[i].getCallerConfigurations(),
                            callers[i].getDependencyDescriptor(), artifact, callersStack)) {
                            // This is what kills us...if it's the a top level exclude, this check shouldn't be happening or it's going to get unexcluded here.
                            return false;
                        }
                    }
                    return true;
                } finally {
                    callersStack.pop();
                }
            }
        
        
        Show
        Luke Renn added a comment - I'm able to fix this issue by making IvyNodeCallers not check the full callers list if it finds the exclusions in the module descriptor. In this case, equinox get re-included when the kernel.userreqion caller is checked (since it's a dependency there). I've got a fix locally, but I'm pretty sure that will break dependency level excludes that really should get reincluded. The relevant code is: IvyCallers.java boolean doesCallersExclude( String rootModuleConf, Artifact artifact, Stack callersStack) { if (callersStack.contains(node.getId())) { return false ; } callersStack.push(node.getId()); try { Caller[] callers = getCallers(rootModuleConf); if (callers.length == 0) { return false ; } for ( int i = 0; i < callers.length; i++) { if (!callers[i].canExclude()) { return false ; } if (!doesExclude(md, rootModuleConf, callers[i].getCallerConfigurations(), callers[i].getDependencyDescriptor(), artifact, callersStack)) { // This is what kills us... if it's the a top level exclude, this check shouldn't be happening or it's going to get unexcluded here. return false ; } } return true ; } finally { callersStack.pop(); } }
        Hide
        Christopher Frost added a comment -

        I had to remove it's ivy cache to keep the file size down so when you run the package command it will download a load of stuff. All to a the local folder and shouldn't taker more than 3 minutes.

        Show
        Christopher Frost added a comment - I had to remove it's ivy cache to keep the file size down so when you run the package command it will download a load of stuff. All to a the local folder and shouldn't taker more than 3 minutes.

          People

          • Assignee:
            Nicolas Lalevée
            Reporter:
            Christopher Frost
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development