Search code examples
javamavenivyartifactoryparent-pom

Programatically resolving POM dependency using ivy, but not source and javadoc


Using this method, I could successfully resolve (but NOT retrieve the actual jars) all dependencies of a library when its organization, name and revision are given, all programatically using Apache Ivy.

During the resolution process, it parses given library's POM and finds a parent POM if specified, and Ivy's POM parser always tries to resolve sources and javadoc, which generally doesn't exist for parent POMs.

The problem is that when a non-existing jar's URL is queried to our local artifactory, it takes 2~3 seconds to refresh its cache, adding up tens of minutes to total dependency resolution time when I have many transitive dependencies having parent POMs.

For example, the following is the log message I get when I try to resolve Google Guava 17.0:

:: loading settings :: url = jar:file:.ivy2/cache/org.apache.ivy/ivy/jars/ivy-2.3.0.jar!/org/apache/ivy/core/settings/ivysettings.xml
:: resolving dependencies :: com.google.guava#guava-envelope;17.0 [not transitive]
    confs: [default]
    validate = true
    refresh = false
resolving dependencies for configuration 'default'
== resolving dependencies for com.google.guava#guava-envelope;17.0 [default]
== resolving dependencies com.google.guava#guava-envelope;17.0->com.google.guava#guava;17.0 [default->master]
        tried http://artifactory/repo/com/google/guava/guava/17.0/guava-17.0.pom
    resolver: found md file for com.google.guava#guava;17.0
        => http://artifactory/repo/com/google/guava/guava/17.0/guava-17.0.pom (17.0)
downloading http://artifactory/repo/com/google/guava/guava/17.0/guava-17.0.pom ...
    resolver: downloading http://artifactory/repo/com/google/guava/guava/17.0/guava-17.0.pom
    [SUCCESSFUL ] com.google.guava#guava;17.0!guava.pom(pom.original) (58ms)
        tried http://artifactory/repo/com/google/guava/guava-parent/17.0/guava-parent-17.0.pom
    resolver: found md file for com.google.guava#guava-parent;17.0
        => http://artifactory/repo/com/google/guava/guava-parent/17.0/guava-parent-17.0.pom (17.0)
downloading http://artifactory/repo/com/google/guava/guava-parent/17.0/guava-parent-17.0.pom ...
    resolver: downloading http://artifactory/repo/com/google/guava/guava-parent/17.0/guava-parent-17.0.pom
    [SUCCESSFUL ] com.google.guava#guava-parent;17.0!guava-parent.pom(pom.original) (20ms)
    resolver: revision in cache: org.sonatype.oss#oss-parent;7
        tried http://artifactory/repo/com/google/guava/guava-parent/17.0/guava-parent-17.0.jar
        tried http://artifactory/repo/com/google/guava/guava-parent/17.0/guava-parent-17.0.jar
        tried http://artifactory/repo/com/google/guava/guava-parent/17.0/guava-parent-17.0-sources.jar
CLIENT ERROR: Could not find resource url=http://artifactory/repo/com/google/guava/guava-parent/17.0/guava-parent-17.0-sources.jar
        tried http://artifactory/repo/com/google/guava/guava-parent/17.0/guava-parent-17.0-src.jar
CLIENT ERROR: Could not find resource url=http://artifactory/repo/com/google/guava/guava-parent/17.0/guava-parent-17.0-src.jar
        tried http://artifactory/repo/com/google/guava/guava-parent/17.0/guava-parent-17.0-javadoc.jar
CLIENT ERROR: Could not find resource url=http://artifactory/repo/com/google/guava/guava-parent/17.0/guava-parent-17.0-javadoc.jar
        tried http://artifactory/repo/com/google/guava/guava/17.0/guava-17.0.jar
        tried http://artifactory/repo/com/google/guava/guava/17.0/guava-17.0-sources.jar
        tried http://artifactory/repo/com/google/guava/guava/17.0/guava-17.0-javadoc.jar
    found com.google.guava#guava;17.0 in resolver
    resolved ivy file produced in cache
:: resolution report :: resolve 2593ms :: artifacts dl 0ms
    :: modules in use:
    com.google.guava#guava;17.0 from resolver in [default]
    ---------------------------------------------------------------------
    |                  |            modules            ||   artifacts   |
    |       conf       | number| search|dwnlded|evicted|| number|dwnlded|
    ---------------------------------------------------------------------
    |      default     |   1   |   1   |   1   |   0   ||   0   |   0   |
    ---------------------------------------------------------------------
    report for com.google.guava#guava-envelope;17.0 default produced in .ivy2/cantabile/com.google.guava-guava-envelope-default.xml
    resolve done (2593ms resolve - 0ms download)

You can see that Ivy wasted a few seconds while trying nonexistent -sources.jar, -src.jar, -javadoc.jar URLs for parent POMs.

Is there an option to disable this behavior when resolving a parent POM? Ideally I don't want to make HTTP requests to any .jars during resolution. Currently I need a programmatic solution but if anyone knows a command line/XML option it will be a great help.

PS: I think this is also the case when using sbt to resolve library dependencies; it takes very long while resolving oss-parent, commons-parent etc.


Solution

  • You need to specify a configuration mapping that excludes both optional dependencies and implicit dependencies like source and javadoc files.

    In an ivy file you'd declare the dependency as follows:

    <dependency org="myorg" name="mymodule" rev="1.0" conf="default"/>
    

    Another option is to declare this dependency mapping as the default for your project.

    <dependencies defaultconfmapping="default">
      <dependency ..
      <dependency ..
    

    See the following SO questions on how to exclude sources and how ivy translates Maven repositories:

    In conclusion Maven modules by default only have a single arefact. More can be stored (like sources and Javadocs) but there is no module metadata listing them. This is why Ivy performs a HTTP request to see if the artefacts exist or not. Changing the configuration mapping settings should help guide ivy to do the right thing :-)

    PS

    I think this can be done by called the "addDependencyConfiguration" method to the DefaultDependencyDescriptor object.