Jar files, snapshot builds and Maven publishing

Hi all:

We have a custom jar plugin that we use to append the build date/time and the Maven “-SNAPSHOT” suffix to the project.version property. The key part of the plugin looks like this:

class MyProjectVersionPlugin implements Plugin<Project> {
    def getSnapshotVersion(buildDate) {
    return "-" + buildDate + "-SNAPSHOT"
  }
    @Override
  void apply(Project project) {
    project.afterEvaluate {
      // The time of this build
      String buildDate = getDate();
        // Is this a release or snapshot build?
      if (!project.hasProperty("release")) {
        // Snapshot build. Append additional build info to the version string.
        project.version += getSnapshotVersion(buildDate);
      }

If we look at the project properties, the project.version is set in the expected way; it looks like 1.0.0 for release builds and 1.0.0-20141204123828-SNAPSHOT for snapshot builds.

The symptoms of the problem are that for snapshot builds, the jar files built in build/libs have names like MyArtifact-1.0.0-20141218195447-SNAPSHOT.jar but the Maven Publisher complains and says that it cannot find MyArtifact-1.0.0.jar. For release builds, the deployment works as expected (i.e. project.version is something like 1.0.0)

console output

:publishMavenJavaPublicationToMavenRepository (Thread[main,5,main]) started.
:publishMavenJavaPublicationToMavenRepository
Executing task ':publishMavenJavaPublicationToMavenRepository' (up-to-date check took 0.0 secs) due to:
  Task has not declared any outputs.
:publishMavenJavaPublicationToMavenRepository FAILED
:publishMavenJavaPublicationToMavenRepository (Thread[main,5,main]) completed. Took 0.048 secs.
  FAILURE: Build failed with an exception.
  * What went wrong:
Execution failed for task ':publishMavenJavaPublicationToMavenRepository'.
> Failed to publish publication 'mavenJava' to repository 'maven'
   > Invalid publication 'mavenJava': artifact file does not exist: '/home/vagrant/projects/src/myproject/api/build/libs/MyArtifact-1.0.0.jar'

In this case project.version is set to 1.0.0-20141218195447-SNAPSHOT and the Java compile/components tasks seem to know that, and produce jar files that are correctly named, but the Maven Publisher does not seem to “know” that the version is different.

I’ve spent some time browsing the DSL reference and looking in the forums, but I haven’t seen anything that looks like a suitable solution to something that should be quite simple. Does our plugin need to modify some properties other than project.version to get the desired behaviour? It feels like we are missing some connection between the Java tasks and the MavenPublish tasks.

Thanks in advance,

The key Gradle files are as follows:

settings.gradle:

rootProject.name = 'MyArtifact'

gradle.properties:

currentVersion=1.0.0
artifactory_user=artifactory
artifactory_password=OP3oKjGilRm6i4aBK89nmGq4qtcP
artifactory_contextUrl=http://artifactory.mycompany.com/artifactory
#org.gradle.jvmargs=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5004
  #systemProp.http.proxyHost=127.0.0.1
#systemProp.http.proxyPort=8888

build.gradle:

apply plugin: 'java'
apply plugin: 'maven'
apply plugin: 'maven-publish'
  // Set the dependencies for this build script, which include the MyProject Version plugin
buildscript {
  dependencies {
    classpath group: 'com.mycompany.myproject.plugins', name: 'version', version: '1+'
  }
    repositories {
    maven { url "${artifactory_contextUrl}/artifactory/libs-release" }
  }
}
  // Set the project version. The MyProject Version plugin will modify this as necessary.
version = "${currentVersion}"
  // Apply the MyProject Version plugin
apply plugin: 'com.mycompany.myproject.plugins.version'
  repositories {
    maven { url "${artifactory_contextUrl}/artifactory/libs-release" }
    maven { url "${artifactory_contextUrl}/artifactory/libs-snapshot" }
}
  // Build dependencies
dependencies {
    compile(group: 'org.foobar', name: 'foobar', version: '1.0')
    compile 'joda-time:joda-time:2.5'
    testCompile group: 'junit', name: 'junit', version: '4.+'
}
  publishing {
    repositories {
        maven {
           credentials {
               username "${artifactory_user}"
               password "${artifactory_password}"
           }
           if ( project.version.endsWith('-SNAPSHOT') ) {
               url "${artifactory_contextUrl}/myproject-snapshot-local"
           } else {
               url "${artifactory_contextUrl}/myproject-release-local"
           }
        }
    }
    publications {
        mavenJava(MavenPublication) {
            groupId 'com.mycompany.myproject'
            artifactId 'myartifact'
            from components.java
        }
    }
}

Hey, I tried to reproduce this issue but couldn’t yet. Does it also fail for you when running ‘publishToMavenLocal’?

cheers, René

I haven’t (yet) tried publishToMavenLocal, but here’s another view of what I am seeing:

$ gradle clean jar
:clean
:compileJava
:processResources UP-TO-DATE
:classes
:jar
  BUILD SUCCESSFUL
  Total time: 4.565 secs
$ ls build/libs/
MyArtifact-1.0.0-20141222100259-SNAPSHOT.jar
$ gradle publish
:generatePomFileForMavenJavaPublication
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:jar
:publishMavenJavaPublicationToMavenRepository
Uploading: com/mycompany/myproject/myartifact/1.0.0-20141222100316-SNAPSHOT/myartifact-1.0.0-20141222100316-20141222.180317-1.jar to repository remote at http://artifactory.mycompany.com/artifactory/myproject-snapshot-local
Transferring 48K from remote
:publishMavenJavaPublicationToMavenRepository FAILED
  FAILURE: Build failed with an exception.
  * What went wrong:
Execution failed for task ':publishMavenJavaPublicationToMavenRepository'.
> Failed to publish publication 'mavenJava' to repository 'maven'
   > Error deploying artifact 'com.mycompany.myproject:myartifact:jar': Error deploying artifact: Resource to deploy not found: File: http://artifactory.mycompany.com/artifactory/myproject-snapshot-local/com/mycompany/myproject/myartifact/1.0.0-20141222100316-SNAPSHOT/myartifact-1.0.0-20141222100316-20141222.180317-1.jar does not exist
  * Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
  BUILD FAILED
  Total time: 3.926 secs

What I find odd is that the snapshot Java compile produces legitimate looking jar files based on the project.version property, but there does not seem to be any connection between the name of jar files produced and the name of of jar files that the Maven publishing task is looking for. When we change the version of the project, do we need to make any changes in properties for the Maven Publisher or it’s POM as well? Perhaps we need to make sure the change in the project.version is done at a different stage of the build?

I tried modifying the Maven repos so that they were local filesystem directories instead of Artifactory, and then “gradle install publish” seems to work:

publishing {
    repositories {
        maven {
           credentials {
               username "${artifactory_user}"
               password "${artifactory_password}"
           }
           if ( project.version.endsWith('-SNAPSHOT') ) {
               url "file:///var/tmp/myrepo/snapshot/"
           } else {
               url "file:///var/tmp/myrepo/release/"
           }
        }
    }
    publications {
        mavenJava(MavenPublication) {
            groupId 'com.mycompany.myproject'
            artifactId 'myartifact'
            from components.java
        }
    }
}

What this looks like is that for snapshot builds, our Artifactory server is rejecting the artifact names that Gradle is proposing. The Artifactory repo is configured with a Maven Snapshot Behaviour of “Deployer”, so I would think it would accept the proposed artifact names? How should the Artifactory repo be configured here?