How to exclude a specific artifact from a consumed ivy dependency

We need to consume an artifact published by another team, using Ivy into a nexus repository. The ivy descriptor is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<ivy-module version="2.0" xmlns:e="http://ant.apache.org/ivy/extra">
    <info organisation="foo.foo.core" module="foo" branch="5.0.0" revision="5.0.0.36-rev546" status="release" publication="20131213163657">
    </info>
              <configurations>
       <conf name="endorsed" visibility="public"/>
       <conf name="default" visibility="public"/>
       <conf name="run" visibility="public" extends="default"/>
       <conf name="compile" visibility="public" extends="default"/>
       <conf name="testing" visibility="public" extends="compile"/>
       <conf name="integration" visibility="public" extends="testing"/>
       <conf name="warstartup" visibility="public"/>
    </configurations>
      <publications defaultconf="default">
        <artifact name="foo-foo-foo" type="bin" ext="jar"/>
        <artifact name="foo-foo-foo" type="test-bin" ext="jar" conf="testing" e:classifier="tests"/>
        <artifact name="foo-foo-foo" type="pom" ext="pom"/>
        <artifact name="foo-foo-foo" type="doc" e:classifier="javadoc" ext="zip"/>
        <artifact name="foo-foo-foo" type="src" e:classifier="sources" ext="zip"/>
    </publications>
      <dependencies defaultconf="default" defaultconfmapping="*->default">
        ...
    </dependencies>
  </ivy-module>

The problem is that the pom artifact gets added to the classpath and the findbugs task tries to open it as zip, printing some annoying exceptions in the logs. Is there some workaround we can use, short of asking the upstream project to fix their descriptor?

Have you tried something like this:

foo
              = ['foo.foo.core:foo:5.0.0.36-rev546', { exclude(group: 'foo.foo.core', module: 'foo-foo-foo') }]
dependencies {
     compile foo
}

That didn’t work and I am not sure what was the expected outcome. The problem was that Gradle was including the following Ivy publication in as an artifact in the Gradle runtime configuration, and I can’t find a way to filter out a single artifact from a dependency:

<artifact name="foo-foo-foo" type="pom" ext="pom"/>

I worked around it like this:

afterEvaluate { Project project ->
    project.tasks.withType(FindBugs) {
        classpath = files(classpath.files).filter
{ it.directory || !it.name.endsWith('.pom') }
    }
}

But it does feel like a Gradle bug, or at least a quirk worth documenting.

Based on Luke Daley’s feedback, I also tried:

configurations.all {
    resolutionStrategy.eachDependency { DependencyResolveDetails details ->
        if (details.requested.group=='foo.foo.core' && details.requested.name=='utils') {
            def requested = details.requested as ExternalModuleDependency
            requested.artifacts.removeAll { it.type == 'pom' }
        }
    }
}

Which failed with:

Cannot cast object 'foo.foo.core:utils:5.0.0.36-rev546' with class 'org.gradle.api.internal.artifacts.DefaultModuleVersionSelector' to class 'org.gradle.api.artifacts.ExternalModuleDependency'

Luke’s comment was:

Looks like the version selector is wrapped here, so it's not going to be possible.

Please raise an issue on the forums with this use case.