Resolve dependencies from parent build job in Jenkins (w/o Nexus or Artifactory)

When performing a build in Jenkins, I want to resolve required jars from a parent build (please don’t suggest to use Nexus or Artifactory…).

The URLs are all of the form https://jenkins/job/mybuild/1234/artifact/path/to/my/library.jar. How do I need to configure the resolver (e.g. URLResolver) in Gradle to make it work?

I tried the following:

repositories {

add(new org.apache.ivy.plugins.resolver.URLResolver()) {

name = "Jenkins "

usepoms = false

descriptor = ‘optional’

changing=true

//addArtifactPattern “${project.ext.baseBuildArtifactsBaseUrl}/[organisation]/[module]/[module]-[revision].[ext]”

// organisation: build job name, e.g. mybuild

// revision: build number

// module: artifact base name without extension [no .jar!]

addArtifactPattern “${project.jenkins.baseUrl}/job/[organisation]/[revision]/artifact/all-libs/[module].[ext]”

} }

Basically I have the same problem as described here: http://gradle.1045684.n5.nabble.com/question-about-urlresolver-td3259653.html

The problem seems to be, that URLResolver is trying to list files (maybe in order to look for an ivy.xml), but all I have are JARs, and there are no directory listings in jenkins

The strange thing is, that gradle actually determines the correct URL: (all messages from logger org.gradle.api.internal.artifacts.ivyservice.IvyLoggingAdaper using gradle --debug)

trying https://buildserver.fluidops.corp/job/fecm/lastBuild/artifact/fecm/deploy/fcoremgmt/lib/fcoremgmt.jar
            tried https://buildserver.fluidops.corp/job/fecm/lastBuild/artifact/fecm/deploy/fcoremgmt/lib/fcoremgmt.jar
HTTP response status: -1 url=https://buildserver.fluidops.corp/job/fecm/lastBuild/artifact/fecm/deploy/fcoremgmt/lib/fcoremgmt.jar
Jenkins : resource not reachable for fecm#fcoremgmt;lastBuild: res=https://buildserver.fluidops.corp/job/fecm/lastBuild/artifact/fecm/deploy/fcoremgmt/lib/fcoremgmt.jar

When I open the specified URL in the browser, I can download my jar.

Which Gradle version are you using? Direct use of Ivy resolvers is discouraged and may no longer be supported in future Gradle versions. Please try by declaring an Ivy repository. See the Gradle user guide for more information.

Which Gradle version are you using?

I’m using Gradle 1.0.

I found out that the actual problem was caused by Ivy’s URLHandlers (HttpClientHandler or BasicURLHandler), which both perform a HEAD request in order to determine whether the artifact exists. Apparently HEAD requests are not supported by Jenkins.

So the solution (or workaround) was to make the URLHandler perform a GET request instead of a HEAD request using this statement (I put it into the buildscript {} closure to make sure that it’s being executed early, I also added the required imports at the top of the file):

URLHandlerRegistry.getDefault().setRequestMethod(URLHandler.REQUEST_METHOD_HEAD)

Direct use of Ivy resolvers is discouraged and may no longer be supported in future Gradle versions.

Please try by declaring an Ivy repository.

Unfortunately I can’t use a proper Ivy repository, but need to download the jars (build artifacts) directly from Jenkins.

I understand that it’s best practice to publish build artifacts in some proper Ivy/Maven repo, but for the cases where this is not possible (for whatever reason), both Gradle and Ivy make it pretty difficult to simply download a JAR from a known URL!

Unfortunately I can’t use a proper Ivy repository, but need to download the jars (build artifacts) directly from Jenkins.

I didn’t mean to say that you should use a repository manager, just that you should use an Ivy repository declaration in your Gradle build script.

both Gradle and Ivy make it pretty difficult to simply download a JAR from a known URL!

If all you want is to download a resource from a known URL, you can use file << url.text or file << url.bytes. Of course then you won’t get any dependency management features like caching. We do plan to add support for that at some point.

thanks for the suggestion.

How would I convert my URLResolver above into a proper Ivy repository definition?

I tried this, but it failed because of missing ivy.xml for the artifact(s):

ivy {
 name = "Jenkins "
 // organisation: build job name, e.g. fecm
 // revision: build number
 // module: artifact base name without extension, e.g. fcoremgmt [no .jar!]
 url = "${project.jenkins.baseUrl}/job/"
 layout 'pattern' , {
  artifact "[organisation]/[revision]/artifact/fecm/deploy/[module]/lib/[module].[ext]"
  //ivy "[organisation]/[revision]/artifact/fecm/deploy/[module]/lib/ivy.xml"
 }
}

If you don’t have an ivy.xml, then you may not be able to use an Ivy repository declaration. If Ivy’s URLResolver doesn’t work for you either, you may have to write your own resolver or implement a solution that bypasses Gradle’s dependency management, until the latter supports downloading from plain URLs.

The URLResolver works for me, when I configure it to perform GET requests instead of HEAD requests (unfortunately that seems to be only possible on a global level) using the following statement somewhere in my Gradle build script:

URLHandlerRegistry.getDefault().setRequestMethod(URLHandler.REQUEST_METHOD_HEAD)

I just would have liked to use an Ivy repo as you wrote that URLHandler might not be supported anymore in the future.