Upgrading to current version, now getting "A POM cannot have multiple artifacts with the same type and classifier"


(Maury Hammel) #1

I’m in the process of upgrading a set of gradle scripts from 1.3 to 3.5. In one of the sub-projects the build.gradle adds a bunch of .png files as artifacts using a custom task. In 1.3, this works fine, but in 3.5, I get the following error:

Execution failed for task ':c.t.p:install'.
> Could not publish configuration 'archives'
   > A POM cannot have multiple artifacts with the same type and classifier. Already have MavenArtifact avatar:image:png:null, trying to add MavenArtifact avatar:image:png:null.

In the sub-project build.gradle:

artifactoryPublish {
   properties {
    webConfig 'c.c.w.c.t.p:c.t.p:*:*@css', deployDirectory: 'c/s/c/t/p'
    webConfig 'c.c.w.c.t.p:c.t.p:*:*@png', deployDirectory: 'c/s/c/t/p/images'
    webConfig 'c.c.w.c.t.p:c.t.p:*:*@gif', deployDirectory: 'c/s/c/t/p/images'
  }
}

compileResources.setEnabled(true)
compileResources {
  inputs.files fileTree(dir: "${rootDir}/../Web/c/s/c/t/p/images", include: '*.*')
  outputs.file file("${buildDir}/c/s/c/t/p/images")

In the main build.gradle:

  task compileResources {
    doLast {
      def target = getOutputs().getFiles().getSingleFile()
      inputs.files.each { File file ->
        // Copy files to build directory
        ant.copy(todir: target, file: file)
        // Add the copied file as an artifact.
        def artifactName = file.name.replaceAll( '(.min)|(.xml)|(.gif)|(.jpg)|(.png)|(.html)', '' )
        def artifactType = ''
        def artifactExtension = ''
        def artifactFile = new File(target, file.name)
        if (file.name.endsWith('.xml'))
        {
          artifactType = 'xml'
          artifactExtension = 'xml'
        }
        else if (file.name.endsWith('.gif'))
        {
          artifactType = 'image'
          artifactExtension = 'gif'
        }
        else if (file.name.endsWith('.jpg'))
        {
          artifactType = 'image'
          artifactExtension = 'jpg'
        }
        else if (file.name.endsWith('.png'))
        {
          artifactType = 'image'
          artifactExtension = 'png'
        }
        else if (file.name.endsWith('.html'))
        {
          artifactType = 'html'
          artifactExtension = 'html'
        }
        addCustomArtifact(project, artifactName, artifactExtension, artifactType, artifactFile, null)
      }
    }
  }

def addCustomArtifact(Project project, String artifactName, String artifactExtension, String artifactType, File artifactFile, String artifactClassifier)
{
  project.configurations.webConfig.getArtifacts().add(
    new DefaultPublishArtifact(artifactName, artifactExtension, artifactType, artifactClassifier, new Date(), artifactFile)
  )
}

Does anyone have any pointers to what I need to do (or what documentation to read) to resolve this error? Is there more information I need to supply? Have I run into a bug?

Oh, in case it matters, the main build.gradle does a “apply plugin: ‘maven’”. I tried replacing that with the maven-publish plugin, but that generated a whole bunch of other errors. :slight_smile:

Thanks in advance.


(Maury Hammel) #2

After digging around some more, I’ve found this example from the Gradle User Guide, section 33.6.4. Maven POM generation

uploadArchives {
  repositories {
    mavenDeployer {
        repository(url: "file://localhost/tmp/myRepo/")
        addFilter('api') {artifact, file ->
            artifact.name == 'api'
        }
        addFilter('service') {artifact, file ->
            artifact.name == 'service'
        }
        pom('api').version = 'mySpecialMavenVersion'
        }
    }
}

Immediately following that is the text:

You need to declare a filter for each artifact you want to publish. This filter defines a boolean expression for which Gradle artifact it accepts. Each filter has a POM associated with it which you can configure.

The problem I have is that the example assumes you know how many/what artifacts you are going to publish, so you can hard-code/configure the pom for each (though I’m not sure how to do that yet), but in my case we want whatever new file is put in the directory to be included as an artifact.

So, any pointers to how I would go about dynamically creating each pom, in addition to modifying the above code to dynamically set up the filters? I tried modifying the above by adding a loop through the collection of artifacts and set up the filters based on each of their names, but the example above is configuration code, so it is run before the uploadArchives task is run and the set of files collected.

Thanks again,