Publishing multiple jars with the Gradle Artifactory plugin

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view

Publishing multiple jars with the Gradle Artifactory plugin

Rich Fromm
I am having a very difficult time figuring out how to get the Gradle
Artifactory plugin to properly publish multiple .jar files from a single

I am able to build both jars fine in Gradle.  It's just the artifactory
publish step that is problematic.

I realize that this is addressed somewhat indirectly both here:

and here:

But not in a sufficient way that I've been able to get things to work.

I'm not going to yet post my entire build file, as I've tried so many
different variants, and I'm not sure which one to post.  I first wanted to
just check on the overall strategy.

In my iteration that is closest to working, I put both jars in the same
"archives" configuration, and differentiate the two using the 'classifier'

--- begin ---
artifacts {
   archives (jarServer.archivePath) {
      name = projectName
      type = 'jar'
      classifier = 'server'
   archives (jarAndroid.archivePath) {
      name = projectName
      type = 'jar'
      classifier = 'android'
--- end ---

But in this case I get a single .pom file, and it doesn't have the
dependency information for either of them.  I assume that if I want proper
dependence info, there ought to be separate .pom files, one for each .jar

If I instead try to differentiate based on the name, I don't think it's
working.  It appears that it's not accepting the name setting below:

--- begin ---
artifacts {
   archives (jarServer.archivePath) {
      name = projectName + '-server'
      type = 'jar'
   archives (jarAndroid.archivePath) {
      name = projectName + '-android'
      type = 'jar'
--- end ---

as I get the following error:

--- begin ---
* What went wrong:
Execution failed for task ':install'.
> Could not publish configuration 'archives'
   > A POM cannot have multiple artifacts with the same type and classifier. Already have MavenArtifact http_java-server:jar:jar:null, trying to add MavenArtifact http_java-server:jar:jar:null.
--- end ---

So then I tried having separate archives* configurations for each jar, rather
than a single "archives" configuration.  Excerpts of the build include the following:

--- begin ---
configurations {

artifacts {
   archivesServer jarServer
   archivesAndroid jarAndroid

artifactoryPublish {
--- end ---

Now I get the following error:

--- begin ---
Publishing to repository 'mavenInstaller'
[ant:null] Error reading settings file '/tmp/gradle_empty_settings2738760698096986778.xml' - ignoring. Error was: /tmp/gradle_empty_settings2738760698096986778.xml (No such file or directory)
--- end ---


--- begin ---
* What went wrong:
A problem was found with the configuration of task ':artifactoryPublish'.
> File '/var/tmp/rich/build/http_java/3.0/poms/pom-default.xml' specified for property 'mavenDescriptor' does not exist.
--- end ---

It's worth noting here that earlier I had added the following code to my
build.gradle, to prevent from generating (and publishing) a useless jar that
was neither the server nor android case:

--- begin ---
// we don't want to end up with a nearly empty (manifest only)
// jar file from the default jar task
jar.enabled = false
// and we don't want to publish it
configurations.archives.artifacts.removeAll { jar }
--- end ---

If I now comment these out, I'm (mostly) back to where I was before.  Both
jars are published to artifactory, but still with a single pom file that has
dependencies for neither.

There are some other problems as well with respect to the naming of the files
within artifactory, but I figured I should deal with the major issues before
worrying about the minor ones.

I eventually want to have multiple jars be published from gradle multi-project
builds as well, but that's not what I'm doing here.  I was hoping that the
single project build case would be an easier starting point, and that the
knowledge of getting that to work would help for the multi-project ase as

Oh yeah, I've also looked at the "gradle-example" at:

but I haven't managed to figure things out from that either.

I'd be most appreciative of any help, either with the overall strategy that's
appropriate here, or specific suggestions, or a pointer to some other docs or

Reply | Threaded
Open this post in threaded view

Re: Publishing multiple jars with the Gradle Artifactory plugin

Rich Fromm
Thanks to the pointer to the source
which includes a multi-project example, I've been able to make a little

My previous efforts dealt with two jars within a single (non-multi) project.
More recently, I've been trying to upload two jars from a multi-project

Let's say I've got a project foo, with 2 subprojects in it, bar and baz.  And
the version is 1.0, but this is a pre-release moving target, so really
1.0-SNAPSHOT using the maven naming convention.  If I do everything in a
somewhat default way, things work okay.  I locally build jars named like:


And they get deployed at:


With corresponding pom files for each at:


But that's not how I actually want things named, filed, or referenced.

What I want, is that if I have a project foo, with a subproject bar, that it
is named "foo-bar".  And if I have a project foo, with a subproject foo, then
I want that named simply "foo".

Internally, we call projects via term "project", and subprojects via the term
"module".  The jars build fine with the following, using the properties
'projectName' and 'moduleName':

--- begin ---
   subprojects {
      jar {
         baseName = "${projectName}"
         if (project.hasProperty('moduleName') && !projectName.equals(moduleName)) {
            appendix = moduleName
--- end ---

The problem comes when these are deployed.  While the jar file is properly
named as I expect, the pom file is not.  And that is leading (somewhat
ironically, since the file is not what I want) to an HTTP 409 Conflict when
trying to upload the pom file.

Also, the path within artifactory is not being properly set to reflect the
"foo-bar" terminology.

Making it more concrete, the project is "ota_java", the version is "2.0", and
the subprojects are "ota_java" and "client".  So I have the following jars:


Below is the first PUT (of the wrongly named pom file for the client jar),
along with the 409 error:

--- begin ---
16:08:48.266 [DEBUG] [org.apache.http.impl.conn.DefaultClientConnection] Sending request: PUT /sandbox-rich/com/locationlabs/client/2.0-SNAPSHOT/client-2.0-SNAPSHOT.pom;;build.timestamp=1391558914670;build.number=1391558916326;ll.dependencies= HTTP/1.1
16:08:48.268 [DEBUG] [org.apache.http.headers] >> PUT /sandbox-rich/com/locationlabs/client/2.0-SNAPSHOT/client-2.0-SNAPSHOT.pom;;build.timestamp=1391558914670;build.number=1391558916326;ll.dependencies= HTTP/1.1
16:08:48.268 [DEBUG] [org.apache.http.headers] >> X-Checksum-Sha1: 91bd77327e9b9ed580bd0ee321ec69a729ea9aba
16:08:48.268 [DEBUG] [org.apache.http.headers] >> X-Checksum-Md5: a74086d006c234db584d231b37ae563f
16:08:48.268 [DEBUG] [org.apache.http.headers] >> Expect: 100-continue
16:08:48.268 [DEBUG] [org.apache.http.headers] >> Content-Length: 411
16:08:48.268 [DEBUG] [org.apache.http.headers] >> Content-Type: binary/octet-stream
16:08:48.269 [DEBUG] [org.apache.http.headers] >> Host:
16:08:48.269 [DEBUG] [org.apache.http.headers] >> Connection: Keep-Alive
16:08:48.269 [DEBUG] [org.apache.http.headers] >> User-Agent: ArtifactoryBuildClient/2.0.15
16:08:48.269 [DEBUG] [org.apache.http.headers] >> Authorization: Basic YnVpbGQ6YnVpbGQ1ODU4
16:08:48.274 [DEBUG] [org.apache.http.impl.conn.DefaultClientConnection] Receiving response: HTTP/1.1 100 Continue
16:08:48.274 [DEBUG] [org.apache.http.headers] << HTTP/1.1 100 Continue
16:08:48.305 [DEBUG] [org.apache.http.impl.conn.DefaultClientConnection] Receiving response: HTTP/1.1 409 Conflict
16:08:48.305 [DEBUG] [org.apache.http.headers] << HTTP/1.1 409 Conflict
16:08:48.305 [DEBUG] [org.apache.http.headers] << Server: Artifactory/3.0.2
16:08:48.305 [DEBUG] [org.apache.http.headers] << X-Artifactory-Id: 86b296ddd78810aa:460c2fb:13fbf7002e2:-8000
16:08:48.306 [DEBUG] [org.apache.http.headers] << Content-Type: text/html;charset=utf-8
16:08:48.306 [DEBUG] [org.apache.http.headers] << Content-Length: 1619
16:08:48.306 [DEBUG] [org.apache.http.headers] << Date: Wed, 05 Feb 2014 00:08:48 GMT
16:08:48.313 [DEBUG] [org.apache.http.impl.client.DefaultHttpClient] Connection can be kept alive indefinitely
16:08:48.317 [DEBUG] [org.apache.http.impl.conn.SingleClientConnManager] Releasing connection org.apache.http.impl.conn.SingleClientConnManager$ConnAdapter@9fa0f19
16:08:48.317 [DEBUG] [org.apache.http.impl.conn.DefaultClientConnection] Connection shut down
16:08:48.318 [DEBUG] [org.gradle.logging.internal.DefaultLoggingConfigurer] Finished configuring with level: DEBUG, configurers: [org.gradle.logging.internal.OutputEventRenderer@5ece2187, org.gradle.logging.internal.logback.LogbackLoggingConfigurer@2efb56b1, org.gradle.logging.internal.JavaUtilLoggingConfigurer@76f8968f]
16:08:48.318 [DEBUG] [org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter] Finished executing task ':ota_java:artifactoryPublish'
16:08:48.318 [LIFECYCLE] [org.gradle.TaskExecutionLogger] :ota_java:artifactoryPublish FAILED
16:08:48.319 [INFO] [org.gradle.execution.taskgraph.AbstractTaskPlanExecutor] :ota_java:artifactoryPublish (Thread[main,5,main]) - complete
16:08:48.319 [DEBUG] [org.gradle.execution.taskgraph.AbstractTaskPlanExecutor] Task worker [Thread[main,5,main]] finished, busy: 11.793 secs, idle: 0.025 secs
16:08:48.324 [ERROR] [org.gradle.BuildExceptionReporter]
16:08:48.325 [ERROR] [org.gradle.BuildExceptionReporter] FAILURE: Build failed with an exception.
16:08:48.325 [ERROR] [org.gradle.BuildExceptionReporter]
16:08:48.325 [ERROR] [org.gradle.BuildExceptionReporter] * What went wrong:
16:08:48.326 [ERROR] [org.gradle.BuildExceptionReporter] Execution failed for task ':ota_java:artifactoryPublish'.
16:08:48.326 [ERROR] [org.gradle.BuildExceptionReporter] > Failed to deploy file: HTTP response code: 409. HTTP response message: Conflict
16:08:48.328 [ERROR] [org.gradle.BuildExceptionReporter]
16:08:48.328 [ERROR] [org.gradle.BuildExceptionReporter] * Exception is:
16:08:48.329 [ERROR] [org.gradle.BuildExceptionReporter] org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':ota_java:artifactoryPublish'.
16:08:48.329 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(
16:08:48.329 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(
16:08:48.329 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.tasks.execution.PostExecutionAnalysisTaskExecuter.execute(
16:08:48.329 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(
16:08:48.330 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(
16:08:48.330 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(
16:08:48.330 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(
16:08:48.330 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(
16:08:48.330 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(
16:08:48.331 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.AbstractTask.executeWithoutThrowingTaskFailure(
16:08:48.331 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.executeTask(
16:08:48.331 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(
16:08:48.331 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.executeTaskWithCacheLock(
16:08:48.331 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$
16:08:48.331 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$
16:08:48.332 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.internal.Factories$1.create(
16:08:48.332 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.cache.internal.DefaultCacheAccess.longRunningOperation(
16:08:48.332 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.cache.internal.DefaultCacheAccess.longRunningOperation(
16:08:48.332 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.cache.internal.DefaultPersistentDirectoryStore.longRunningOperation(
16:08:48.332 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.changedetection.state.DefaultTaskArtifactStateCacheAccess.longRunningOperation(
16:08:48.333 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.process(
16:08:48.333 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(
16:08:48.333 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.execution.SelectedTaskExecutionAction.execute(
16:08:48.333 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.execution.DefaultBuildExecuter.execute(
16:08:48.333 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.execution.DefaultBuildExecuter.access$200(
16:08:48.333 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.execution.DefaultBuildExecuter$2.proceed(
16:08:48.334 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.execution.DryRunBuildExecutionAction.execute(
16:08:48.334 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.execution.DefaultBuildExecuter.execute(
16:08:48.334 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.execution.DefaultBuildExecuter.execute(
16:08:48.334 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(
16:08:48.334 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.initialization.DefaultGradleLauncher.doBuild(
16:08:48.335 [ERROR] [org.gradle.BuildExceptionReporter] at
16:08:48.335 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.launcher.exec.InProcessBuildActionExecuter$
16:08:48.335 [ERROR] [org.gradle.BuildExceptionReporter] at
16:08:48.335 [ERROR] [org.gradle.BuildExceptionReporter] at
16:08:48.335 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(
16:08:48.335 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(
16:08:48.336 [ERROR] [org.gradle.BuildExceptionReporter] at
16:08:48.336 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.Actions$RunnableActionAdapter.execute(
16:08:48.336 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(
16:08:48.336 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(
16:08:48.336 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(
16:08:48.336 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(
16:08:48.337 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.launcher.cli.ExceptionReportingAction.execute(
16:08:48.337 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.launcher.cli.ExceptionReportingAction.execute(
16:08:48.337 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.launcher.Main.doAction(
16:08:48.337 [ERROR] [org.gradle.BuildExceptionReporter] at
16:08:48.337 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.launcher.Main.main(
16:08:48.399 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.launcher.bootstrap.ProcessBootstrap.runNoExit(
16:08:48.399 [ERROR] [org.gradle.BuildExceptionReporter] at
16:08:48.399 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.launcher.GradleMain.main(
16:08:48.399 [ERROR] [org.gradle.BuildExceptionReporter] Caused by: Failed to deploy file: HTTP response code: 409. HTTP response message: Conflict
16:08:48.399 [ERROR] [org.gradle.BuildExceptionReporter] at
16:08:48.400 [ERROR] [org.gradle.BuildExceptionReporter] at
16:08:48.400 [ERROR] [org.gradle.BuildExceptionReporter] at
16:08:48.400 [ERROR] [org.gradle.BuildExceptionReporter] at org.jfrog.gradle.plugin.artifactory.extractor.BuildInfoTask.deployArtifacts(
16:08:48.400 [ERROR] [org.gradle.BuildExceptionReporter] at org.jfrog.gradle.plugin.artifactory.extractor.BuildInfoTask.prepareAndDeploy(
16:08:48.400 [ERROR] [org.gradle.BuildExceptionReporter] at org.jfrog.gradle.plugin.artifactory.extractor.BuildInfoTask.collectProjectBuildInfo(
16:08:48.401 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.BeanDynamicObject$MetaClassAdapter.invokeMethod(
16:08:48.401 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.BeanDynamicObject.invokeMethod(
16:08:48.401 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.CompositeDynamicObject.invokeMethod(
16:08:48.401 [ERROR] [org.gradle.BuildExceptionReporter] at org.jfrog.gradle.plugin.artifactory.extractor.BuildInfoTask_Decorated.invokeMethod(Unknown Source)
16:08:48.401 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.BeanDynamicObject$MetaClassAdapter.invokeMethod(
16:08:48.401 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.BeanDynamicObject.invokeMethod(
16:08:48.402 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.CompositeDynamicObject.invokeMethod(
16:08:48.402 [ERROR] [org.gradle.BuildExceptionReporter] at org.jfrog.gradle.plugin.artifactory.extractor.BuildInfoTask_Decorated.invokeMethod(Unknown Source)
16:08:48.402 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.util.ReflectionUtil.invoke(ReflectionUtil.groovy:23)
16:08:48.402 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.doExecute(
16:08:48.402 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(
16:08:48.402 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(
16:08:48.403 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(
16:08:48.403 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(
16:08:48.403 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(
16:08:48.403 [ERROR] [org.gradle.BuildExceptionReporter] at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(
16:08:48.403 [ERROR] [org.gradle.BuildExceptionReporter] ... 50 more
16:08:48.403 [ERROR] [org.gradle.BuildExceptionReporter]
16:08:48.404 [LIFECYCLE] [org.gradle.BuildResultLogger]
16:08:48.404 [LIFECYCLE] [org.gradle.BuildResultLogger] BUILD FAILED
16:08:48.404 [LIFECYCLE] [org.gradle.BuildResultLogger]
16:08:48.404 [LIFECYCLE] [org.gradle.BuildResultLogger] Total time: 18.939 secs
--- end ---

If I comment out the jar closure shown above (setting basename and appendix),
I end up with jars named as follows:


These do publish fine to artifactory, just not the way I want.  Although
looking at the output below, there are still two things that confuse me:

* There are 5 PUT operations, not 4.  One of the jars initially fails with a
  404, and then later succeeds with a 201.  Why?

* As far as I can tell, artifactory is just accepting files passed to it with
  this call:

  Where do the pom files come from?  There's no record of them in the buildDir
  afterwards.  Is the pom file generated based on the standard maven plugin?
  Is there any way to get the pom file to remain afterwards?

I am using gradle 1.7 and build-info-extractor-gradle 2.0.17.  I am willing to
upgrade either or both of these if that will help solve this problem.

--- begin ---
16:12:09.809 [DEBUG] [org.apache.http.impl.conn.DefaultClientConnection] Sending request: PUT /sandbox-rich/com/locationlabs/client/2.0-SNAPSHOT/client-2.0-SNAPSHOT.pom;;build.timestamp=1391559116354;build.number=1391559118007;ll.dependencies= HTTP/1.1
16:12:09.810 [DEBUG] [org.apache.http.headers] >> PUT /sandbox-rich/com/locationlabs/client/2.0-SNAPSHOT/client-2.0-SNAPSHOT.pom;;build.timestamp=1391559116354;build.number=1391559118007;ll.dependencies= HTTP/1.1
16:12:09.811 [DEBUG] [org.apache.http.headers] >> X-Checksum-Sha1: b81f7cf6326f86a3623e1ac357ded65e34bc92bc
16:12:09.811 [DEBUG] [org.apache.http.headers] >> X-Checksum-Md5: a71069292df17a423e26a6ac79e8240e
16:12:09.811 [DEBUG] [org.apache.http.headers] >> Expect: 100-continue
16:12:09.811 [DEBUG] [org.apache.http.headers] >> Content-Length: 402
16:12:09.811 [DEBUG] [org.apache.http.headers] >> Content-Type: binary/octet-stream
16:12:09.811 [DEBUG] [org.apache.http.headers] >> Host:
16:12:09.811 [DEBUG] [org.apache.http.headers] >> Connection: Keep-Alive
16:12:09.811 [DEBUG] [org.apache.http.headers] >> User-Agent: ArtifactoryBuildClient/2.0.15
16:12:09.812 [DEBUG] [org.apache.http.headers] >> Authorization: Basic YnVpbGQ6YnVpbGQ1ODU4
16:12:09.816 [DEBUG] [org.apache.http.impl.conn.DefaultClientConnection] Receiving response: HTTP/1.1 100 Continue
16:12:09.816 [DEBUG] [org.apache.http.headers] << HTTP/1.1 100 Continue
16:12:09.833 [DEBUG] [org.apache.http.impl.conn.DefaultClientConnection] Receiving response: HTTP/1.1 201 Created
16:12:09.833 [DEBUG] [org.apache.http.headers] << HTTP/1.1 201 Created
16:12:09.833 [DEBUG] [org.apache.http.headers] << Server: Artifactory/3.0.2
16:12:09.833 [DEBUG] [org.apache.http.headers] << X-Artifactory-Id: 86b296ddd78810aa:460c2fb:13fbf7002e2:-8000
16:12:09.834 [DEBUG] [org.apache.http.headers] << Location:
16:12:09.834 [DEBUG] [org.apache.http.headers] << Content-Type: application/;charset=ISO-8859-1
16:12:09.834 [DEBUG] [org.apache.http.headers] << Transfer-Encoding: chunked
16:12:09.834 [DEBUG] [org.apache.http.headers] << Date: Wed, 05 Feb 2014 00:12:09 GMT
--- end ---

--- begin ---
16:12:10.242 [DEBUG] [org.apache.http.impl.conn.DefaultClientConnection] Sending request: PUT /sandbox-rich/com/locationlabs/ota_java/2.0-SNAPSHOT/ota_java-2.0-SNAPSHOT.pom;;build.timestamp=1391559116354;build.number=1391559118007;ll.dependencies= HTTP/1.1
16:12:10.242 [DEBUG] [org.apache.http.headers] >> PUT /sandbox-rich/com/locationlabs/ota_java/2.0-SNAPSHOT/ota_java-2.0-SNAPSHOT.pom;;build.timestamp=1391559116354;build.number=1391559118007;ll.dependencies= HTTP/1.1
16:12:10.243 [DEBUG] [org.apache.http.headers] >> X-Checksum-Sha1: 7ed6c2d314cbf922e323065abbec7d0552db86a9
16:12:10.243 [DEBUG] [org.apache.http.headers] >> X-Checksum-Md5: e32ada727bbadde33bee95d58b2cd3d3
16:12:10.243 [DEBUG] [org.apache.http.headers] >> Expect: 100-continue
16:12:10.243 [DEBUG] [org.apache.http.headers] >> Content-Length: 805
16:12:10.243 [DEBUG] [org.apache.http.headers] >> Content-Type: binary/octet-stream
16:12:10.243 [DEBUG] [org.apache.http.headers] >> Host:
16:12:10.243 [DEBUG] [org.apache.http.headers] >> Connection: Keep-Alive
16:12:10.243 [DEBUG] [org.apache.http.headers] >> User-Agent: ArtifactoryBuildClient/2.0.15
16:12:10.243 [DEBUG] [org.apache.http.headers] >> Authorization: Basic YnVpbGQ6YnVpbGQ1ODU4
16:12:10.245 [DEBUG] [org.apache.http.impl.conn.DefaultClientConnection] Receiving response: HTTP/1.1 100 Continue
16:12:10.245 [DEBUG] [org.apache.http.headers] << HTTP/1.1 100 Continue
16:12:10.405 [DEBUG] [org.apache.http.impl.conn.DefaultClientConnection] Receiving response: HTTP/1.1 201 Created
16:12:10.405 [DEBUG] [org.apache.http.headers] << HTTP/1.1 201 Created
16:12:10.405 [DEBUG] [org.apache.http.headers] << Server: Artifactory/3.0.2
16:12:10.406 [DEBUG] [org.apache.http.headers] << X-Artifactory-Id: 86b296ddd78810aa:460c2fb:13fbf7002e2:-8000
16:12:10.406 [DEBUG] [org.apache.http.headers] << Location:
16:12:10.406 [DEBUG] [org.apache.http.headers] << Content-Type: application/;charset=ISO-8859-1
16:12:10.406 [DEBUG] [org.apache.http.headers] << Transfer-Encoding: chunked
16:12:10.406 [DEBUG] [org.apache.http.headers] << Date: Wed, 05 Feb 2014 00:12:09 GMT
--- end ---

--- begin ---
16:12:10.410 [DEBUG] [org.apache.http.impl.conn.DefaultClientConnection] Sending request: PUT /sandbox-rich/com/locationlabs/ota_java/2.0-SNAPSHOT/ota_java-2.0-SNAPSHOT.jar;;build.timestamp=1391559116354;build.number=1391559118007;ll.dependencies= HTTP/1.1
16:12:10.410 [DEBUG] [org.apache.http.headers] >> PUT /sandbox-rich/com/locationlabs/ota_java/2.0-SNAPSHOT/ota_java-2.0-SNAPSHOT.jar;;build.timestamp=1391559116354;build.number=1391559118007;ll.dependencies= HTTP/1.1
16:12:10.410 [DEBUG] [org.apache.http.headers] >> X-Checksum-Sha1: 91d4699fc7cf20679a987d3b30bbeefa0a6a1629
16:12:10.410 [DEBUG] [org.apache.http.headers] >> X-Checksum-Md5: ad790169f00f1d7b6a9e0bb72aa7c379
16:12:10.410 [DEBUG] [org.apache.http.headers] >> X-Checksum-Deploy: true
16:12:10.410 [DEBUG] [org.apache.http.headers] >> Content-Length: 0
16:12:10.410 [DEBUG] [org.apache.http.headers] >> Host:
16:12:10.411 [DEBUG] [org.apache.http.headers] >> Connection: Keep-Alive
16:12:10.411 [DEBUG] [org.apache.http.headers] >> User-Agent: ArtifactoryBuildClient/2.0.15
16:12:10.411 [DEBUG] [org.apache.http.headers] >> Authorization: Basic YnVpbGQ6YnVpbGQ1ODU4
16:12:10.414 [DEBUG] [org.apache.http.impl.conn.DefaultClientConnection] Receiving response: HTTP/1.1 404 Not Found
16:12:10.414 [DEBUG] [org.apache.http.headers] << HTTP/1.1 404 Not Found
16:12:10.414 [DEBUG] [org.apache.http.headers] << Server: Artifactory/3.0.2
16:12:10.415 [DEBUG] [org.apache.http.headers] << X-Artifactory-Id: 86b296ddd78810aa:460c2fb:13fbf7002e2:-8000
16:12:10.415 [DEBUG] [org.apache.http.headers] << Content-Type: text/html;charset=utf-8
16:12:10.415 [DEBUG] [org.apache.http.headers] << Content-Length: 1133
16:12:10.415 [DEBUG] [org.apache.http.headers] << Date: Wed, 05 Feb 2014 00:12:09 GMT
--- end ---

--- begin ---
16:12:10.420 [DEBUG] [org.apache.http.impl.conn.DefaultClientConnection] Sending request: PUT /sandbox-rich/com/locationlabs/ota_java/2.0-SNAPSHOT/ota_java-2.0-SNAPSHOT.jar;;build.timestamp=1391559116354;build.number=1391559118007;ll.dependencies= HTTP/1.1
16:12:10.420 [DEBUG] [org.apache.http.headers] >> PUT /sandbox-rich/com/locationlabs/ota_java/2.0-SNAPSHOT/ota_java-2.0-SNAPSHOT.jar;;build.timestamp=1391559116354;build.number=1391559118007;ll.dependencies= HTTP/1.1
16:12:10.420 [DEBUG] [org.apache.http.headers] >> X-Checksum-Sha1: 91d4699fc7cf20679a987d3b30bbeefa0a6a1629
16:12:10.420 [DEBUG] [org.apache.http.headers] >> X-Checksum-Md5: ad790169f00f1d7b6a9e0bb72aa7c379
16:12:10.421 [DEBUG] [org.apache.http.headers] >> Expect: 100-continue
16:12:10.421 [DEBUG] [org.apache.http.headers] >> Content-Length: 119235
16:12:10.421 [DEBUG] [org.apache.http.headers] >> Content-Type: binary/octet-stream
16:12:10.421 [DEBUG] [org.apache.http.headers] >> Host:
16:12:10.421 [DEBUG] [org.apache.http.headers] >> Connection: Keep-Alive
16:12:10.421 [DEBUG] [org.apache.http.headers] >> User-Agent: ArtifactoryBuildClient/2.0.15
16:12:10.421 [DEBUG] [org.apache.http.headers] >> Authorization: Basic YnVpbGQ6YnVpbGQ1ODU4
16:12:10.423 [DEBUG] [org.apache.http.impl.conn.DefaultClientConnection] Receiving response: HTTP/1.1 100 Continue
16:12:10.423 [DEBUG] [org.apache.http.headers] << HTTP/1.1 100 Continue
16:12:10.444 [DEBUG] [org.apache.http.impl.conn.DefaultClientConnection] Receiving response: HTTP/1.1 201 Created
16:12:10.445 [DEBUG] [org.apache.http.headers] << HTTP/1.1 201 Created
16:12:10.445 [DEBUG] [org.apache.http.headers] << Server: Artifactory/3.0.2
16:12:10.445 [DEBUG] [org.apache.http.headers] << X-Artifactory-Id: 86b296ddd78810aa:460c2fb:13fbf7002e2:-8000
16:12:10.445 [DEBUG] [org.apache.http.headers] << Location:
16:12:10.445 [DEBUG] [org.apache.http.headers] << Content-Type: application/;charset=ISO-8859-1
16:12:10.445 [DEBUG] [org.apache.http.headers] << Transfer-Encoding: chunked
16:12:10.445 [DEBUG] [org.apache.http.headers] << Date: Wed, 05 Feb 2014 00:12:09 GMT
--- end ---

--- begin ---
16:12:10.449 [DEBUG] [org.apache.http.impl.conn.DefaultClientConnection] Sending request: PUT /sandbox-rich/com/locationlabs/client/2.0-SNAPSHOT/client-2.0-SNAPSHOT.jar;;build.timestamp=1391559116354;build.number=1391559118007;ll.dependencies= HTTP/1.1
16:12:10.449 [DEBUG] [org.apache.http.headers] >> PUT /sandbox-rich/com/locationlabs/client/2.0-SNAPSHOT/client-2.0-SNAPSHOT.jar;;build.timestamp=1391559116354;build.number=1391559118007;ll.dependencies= HTTP/1.1
16:12:10.449 [DEBUG] [org.apache.http.headers] >> X-Checksum-Sha1: 1ccc31b0476ba44b336529448391c20105a8d67e
16:12:10.450 [DEBUG] [org.apache.http.headers] >> X-Checksum-Md5: abb5e3df09f61cb947abed3f98af6ac0
16:12:10.450 [DEBUG] [org.apache.http.headers] >> Expect: 100-continue
16:12:10.450 [DEBUG] [org.apache.http.headers] >> Content-Length: 6226
16:12:10.450 [DEBUG] [org.apache.http.headers] >> Content-Type: binary/octet-stream
16:12:10.450 [DEBUG] [org.apache.http.headers] >> Host:
16:12:10.450 [DEBUG] [org.apache.http.headers] >> Connection: Keep-Alive
16:12:10.450 [DEBUG] [org.apache.http.headers] >> User-Agent: ArtifactoryBuildClient/2.0.15
16:12:10.451 [DEBUG] [org.apache.http.headers] >> Authorization: Basic YnVpbGQ6YnVpbGQ1ODU4
16:12:10.451 [DEBUG] [org.apache.http.impl.conn.DefaultClientConnection] Receiving response: HTTP/1.1 100 Continue
16:12:10.452 [DEBUG] [org.apache.http.headers] << HTTP/1.1 100 Continue
16:12:10.467 [DEBUG] [org.apache.http.impl.conn.DefaultClientConnection] Receiving response: HTTP/1.1 201 Created
16:12:10.467 [DEBUG] [org.apache.http.headers] << HTTP/1.1 201 Created
16:12:10.468 [DEBUG] [org.apache.http.headers] << Server: Artifactory/3.0.2
16:12:10.468 [DEBUG] [org.apache.http.headers] << X-Artifactory-Id: 86b296ddd78810aa:460c2fb:13fbf7002e2:-8000
16:12:10.468 [DEBUG] [org.apache.http.headers] << Location:
16:12:10.468 [DEBUG] [org.apache.http.headers] << Content-Type: application/;charset=ISO-8859-1
16:12:10.468 [DEBUG] [org.apache.http.headers] << Transfer-Encoding: chunked
16:12:10.468 [DEBUG] [org.apache.http.headers] << Date: Wed, 05 Feb 2014 00:12:09 GMT
--- end ---
Reply | Threaded
Open this post in threaded view

Re: Publishing multiple jars with the Gradle Artifactory plugin

Rich Fromm
I'm not sure if this solves all my problems, but I've made significant progress by just naming the subprojects exactly the way that I ultimately want them.  In other words, rather than rely on the "client" subproject within the "ota_java" project to somehow concatenate to "ota_java-client" via any tools, just rename the actual directory in git to be "ota_java-client".
Reply | Threaded
Open this post in threaded view

Re: Publishing multiple jars with the Gradle Artifactory plugin

Rich Fromm
I was able to finally get things to work, for both of my cases (multiple jars
because of multiple variants, and multiple jars because of dependencies in a
true multi-project scenario), and I thought I'd share a little bit of my
experience, in case it helps someone in the future.

I can't just pinpoint a single solution, because it really was a multi-faceted
problem.  And one that, in retrospect, I can see would have been somewhat hard
to answer from just the questions that I asked, since it involved navigating
through more than just my project(s), but common build-related *.gradle files
that are shared across the organization.

I recommend taking a look at the multiproject example, and even trying to
build it yourself, that is included with the gradle artifactory plugin.  That
helped initially point me in the right direction for solving my problems.  You
can find it here:


As I was pointed to from here:


My initial report of progress by renaming the subprojects was somewhat of a
false solution.  The source of that problem was that there was common code
regarding the publishing to artifactory that was setting archivesBaseName.
And it wasn't accounting for the multi-project scenario, which meant that what
I wanted my artifacts to be named and what they were actually named wasn't
matching.  And I think this may have been the source of some HTTP 409 Conflict

One big aspect of understanding this all was the realization that a lot of
what I thought was the domain of the artifactory plugin was really the domain
of the maven plugin.  So saying that something is going wrong with artifactory
may not really be true.  Read through and pay attention to documentation for
the maven plugin.  I realize that invoking the artifactory plugin somehow (I
haven't yet traced down where or how this happens) ends up automatically
generating a pom file, and that pom file is published to artifactory but not
saved locally (aside -- can you override this?  I'd love to end up with a copy
in my buildDir as a side effect).  But you can also use the maven plugin
directly to generate a pom file.  If that doesn't look correct (e.g. is
missing dependency info), that might be a sign of something suspicious.

One big question I had was, for multiple artifacts, should I differentiate
them by different names (e.g. foo-bar and foo-baz), or use the same name and
differentiate by classifier.  Exactly when you ought to use classifier seems
to be a topic of some argument.  But I think this sums it up pretty nicely:


    "The classifier allows to distinguish artifacts that were built from the
    same POM but differ in their content."

So if the dependencies might be different, then the POMs should be different,
and you should differentiate via name, and not classifier.  I've decided to
reserve using classifier solely for different types of artifacts
(e.g. javadoc jar, source jar) from the same actual sources.

But maven doesn't really seem to like the idea of multiple POMs per project.
Nevertheless, gradle doesn't think this is a bad idea, and the maven plugin
does allegedly support it.  See the following:


I was never able to get this to work.  I could get the maven plugin to
generate multiple POMs, but they didn't have the dependency info right.  I
thought that I had found the solution, and that all I had to do was add the
configurations that mattered to the relevant Conf2ScopeMappingContainer, as
described here:


But I just couldn't get it to work, and eventually abandoned that effort.  I
welcome a response from someone who has successfully used the ideas discussed
in these two sections of the maven plugin docs in the context of artifactory.

For SNAPSHOT builds, at least, internally in artifactory, artifacts are stored

* ${name}-${version}-${yyyy}${mm}${dd}.${hh}${mm}${ss}-${num}.jar

On many occasions when things weren't working properly, I'd instead just get:

* ${name}-${version}-SNAPSHOT.jar

I'm not positive now in retrospect, but I think that may have been a sign that
the POM wasn't being uploaded.

What I did instead to properly generate multiple POMs was to use a
multi-project build.  If I want another regular jar file, then it comes from a
different subproject.  I think this actually ended up as a cleaner solution
than one that relied on solely on different sourceSets and configurations for
the different variants.

Note that while each jar is coming from a different subproject, each subdir
doesn't have to actually be a real project with a real artifact.  In one of my
cases, I wanted an android and a server variant.  The vast majority of the
code is common.  That's in a common subdir, but it's technically not a
subproject (it's not pointed to by the top level settings.gradle).  Then there
are really two different subprojects, which each produce a single jar, and I
reference the two dirs (common plus unique) via a Set of srcDirs in the

Which was another revelation, that srcDirs must be a Set, not a List.  And
Groovy doesn't provide any simple shorthand that I know of for declaring a
set, but you can take the "[]" notation of the List and make it a set with
either ".toSet()" or " as Set" as a suffix.

Carefully paying attention to what happened and was applied where, and
properly differentiating in the build.gradle file for the root project between
what's in the top level file, and what's in the allprojects{} closure, and
what's in the subprojects{} closure, was also important.

And if you don't want a nearly empty (manifest only) jar file for the root
project, and you don't want that published to artifactory, you probably want
the following in the build.gradle for your root project.

    artifactoryPublish.skip = true
    jar.enabled = false

One final important realization was that, in general, properties are inherited
from parent projects to child projects.  See the discussion about the 5
different property "scopes" in the Project DSL:


Often, this is what you want.  But not always.

Note that project.hasProperty('foo') will return whether or not the property
exists anywhere in the chain leading to the current project.  If you only want
to check whether the exact current project has that property defined, and not
to inherit it from a parent project, you can use'foo').

I hope that perhaps some of this might be of help at some point in the future
to someone else experiencing similar problems.