Dependency in a custom configuration is not being added to the POM

In a gradle file, I have: (snippet)

apply plugin: 'artifactory-publish'
apply plugin: 'maven-publish'
  configuration {
  myConfig {
    description = "my dependencies"
    transitive = true
  }
}
  dependencies {
  myConfig group: 'com.myCompany', name: 'depArt', version: 'LATEST-SNAPSHOT', ext: 'tar', classifier: 'rhel6-x86_64'
}
  publishing {
  publications {
    myArtifacts( MavenPublication ) {
      artifact( file ( "${buildDir}/distributions/${project.name}.tar" ) ) {
        classifier project.classifier
      }
    }
  }
}

When I publish this to artifactory (or just dump out the generated POM) the dependency is not listed in the pom.xml.

I know I can force it by doing:

publishing {
  publications {
    myArtifacts( MavenPublication ) {
      artifact( file ( "${buildDir}/distributions/${project.name}.tar" ) ) {
        classifier project.classifier
      }
      pom.withXml {
        def node = asNode().appendNode( 'dependencies').appendNode( 'dependency' )
        node.appendNode( 'groupId', 'com.myCompany' )
        node.appendNode( 'artifactId', 'depArt' )
        node.appendNode( 'version', 'LATEST-SNAPSHOT' )
        node.appendNode( 'classifier', 'rhel6-x86_64' )
        node.appendNode( 'scope', 'myConfig' )
      }
    }
  }
}

but its going to be a pain to do it myself with lots of dependencies. It really seems like this should be automatic… I’ve seen examples online where other people appear to have it working for them.

http://stackoverflow.com/questions/17281927/how-to-make-gradle-generate-a-valid-pom-xml-file-at-the-root-of-a-project-for-ma

Of course, that appears to be a java example, and it should be fairly obvious I’m dealing with native artifacts.

Since transitive dependency resolution doesn’t appear to work for custom configurations, I need this information in the pom file so I can at least write my own transitive resolution code… (That’s the end result of what I’m trying to get to).

Thank you.

Custom configurations cannot be automatically included in the POM, because Gradle cannot possibly know which configurations to include, and which Maven scopes to map them to. (You cannot have a scope ‘myConfig’ in Maven, because Maven only supports a fixed set of scopes.) The old ‘maven’ plugin has an API to do such a mapping, but I think the new ‘maven-publish’ plugin does not (yet). However, you can write some code that iterates over a configuration’s dependencies and generates the appropriate XML.

Transitive dependency resolution works fine for custom configurations.

Transitive Dependencies…

You say they work for custom configurations… is this limited to Java, or are you saying they should also work for native/c++ as well? seems to me they should would for both because gradle interacts with Artifactory which defines the dependency in the .pom file. If so, I could use a little help figuring out why its not working like I expect.

I have an artifactory server with ‘maven’ repositories My artifacts are .tar archives

I have 3 projects: hello firstLevelDependency secondLevelDependency.

These are all native projects.

  • ‘secondLevelDependency’ is built and stored in artifactory

  • ‘firstLevelDependency’ depends on secondLevelDependency which is downloaded when I build. When I deploy this to Artifactory I customize the pom to contain the dependency information:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.myCompany.connectivity.test</groupId>
  <artifactId>firstLevelDependency</artifactId>
  <version>LATEST-SNAPSHOT</version>
  <packaging>pom</packaging>
  <dependencies>
    <dependency>
      <groupId>com.myCompany.connectivity.test</groupId>
      <artifactId>secondLevelDependency</artifactId>
      <version>LATEST-SNAPSHOT</version>
      <classifier>rhel6-x86_64</classifier>
      <scope>nativeLibrary</scope>
      <type>tar</type>
    </dependency>
  </dependencies>
</project>
  • ‘hello’ depends on firstLevelDependency.

If I delete ~/.gradle/caches, and build ‘hello’, it is only downloading ‘firstLevelDependency’, and not the transitive dependency ‘secondLevelDependency’.

I have a custom configuration ‘nativeLibrary’ which I add my dependencies to.

I have a task “ensureDependencies” (defined in a custom plugin):

project.task( 'ensureDependencies' ) << {
  project.configurations.nativeLibrary.files.each { depFile ->
    // I untar the file to a desired location
  }
}

My understanding is that “files” on the configuration should have resolved all the transitive dependencies.

I am close to writing code that will manually parse the .pom file that it downloaded, to find the dependencies myself… and then get those myself and. repeat. But it really seems like there should be a way to get gradle to work such that I don’t have to do this.

Was it a poor choice to use maven style repositories? (chosen because I like the forced structure). My understanding is that Ivy is very… umm… “loose” and would depend on developers being responsible to keep it organized.

The most important thing for my effort is to have transitive dependencies for my .tar artifacts to be defined and downloaded.

Thanks.

One problem that I can spot is that ‘nativeLibrary’ is not a valid Maven scope (try ‘compile’). Not sure how well packaging ‘pom’ is supported by now.

I’ve changed the scope of my ‘firstLevelDependency’ to “compile” from “nativeLibrary”, so that is what it says in the pom now. I’ve changed my custom configuration name to “compile” (I’m not using the java plugin), so I have to create the “compile” configuration myself. I updated everything to use the compile configuration.

If I try using the ‘java’ plugin to have it provide the compile configuration, it complains that it can’t find the "compile() for arguments… because it doesn’t like the arguments/properties that are needed to define the tar artifact.

Please show the relevant code and exact error message. Using ‘ext:’ effectively disables transitive dependency resolution because it requests an artifact rather than a module.

But, that is the problem that I’m trying to solve. My artifacts are native .tar files containing headers and libs.

if I remove the “ext” then it attempts to download my artifact as a .jar

So, it sounds like transitive dependencies won’t inherently work if the dependencies are .tar artifacts, or, I need to try bundling my native artifacts as jar files instead of .tar

Am I approaching this problem the wrong way? I can provide examples, but before I do, I’d like to make sure the approach is correct.

Thanks.

If you want transitive resolution, you need to set ‘tar’ in the POMs (by setting the packaging element), rather than in the build script. If that doesn’t work, then transitive resolution isn’t currently possible for Tars.

As for approaching the problem in the right way, Maven dependency management wasn’t designed for the native world, and isn’t a great fit. Ivy does somewhat better, but ultimately isn’t powerful enough either.

unfortunately it seems that Gradle will not respect “tar” transitive dependencies in Artfiactory. I changed the element in my first level dependendency to “tar”, and I removed the “ext: 'tar” from my projects dependency specification, this results in gradle downloading both my first and second level .pom files, but then it fails trying to download the firstLevelDependency because it is assuming that it is looking for a Jar, despite the packaging being listed as a “tar”.

It seems like support in gradle is close, it just needs to be enhance to respect the pom files a bit better?

In the mean time, I will have to Kluge a solution together to resolve the transitive dependencies myself.

Thanks for the information in trying to resolve this.