publishToMavenLocal not (always) including all classes

Hi Gradle folks,

I have observed a weird and usually-but-not-always-reproducible phenomenon with one of my Gradle subprojects: when I include this directive:

java {
  // IntelliJ can also use the sources jar, published to the same location.
  withSourcesJar()
}

The resulting classes jar placed in my ~/.m2 repository will not always contain all of the class files. It will contain about half of them. Though the behavior appears somewhat intermittent. Commenting out the withSourcesJar() line and re-running publishToMavenLocal will usually fix the problem.

The subproject was ported to Kotlin but I kept the classes in src/main/java and added

sourceSets {
    main.java.srcDirs += "src/main/java"
}

Here is the entire build file in case it’s helpful:

apply plugin: 'java'
apply plugin: 'kotlin'

apply plugin: 'maven-publish'

// This sets the jar name to wyvern-auth-1.1.jar
version = '1.1'

repositories {
  mavenCentral()
}

// Required for App Engine.
sourceCompatibility = '1.8'
targetCompatibility = '1.8'

dependencies {
  implementation 'commons-io:commons-io:2.4'
  runtimeOnly 'commons-io:commons-io:2.4'

  implementation 'org.twitter4j:twitter4j-core:4.0.5'
  runtimeOnly 'org.twitter4j:twitter4j-core:4.0.5'

  implementation 'com.restfb:restfb:1.30.0'
  runtimeOnly 'com.restfb:restfb:1.30.0'

  implementation 'org.json:json:20160212'
  runtimeOnly 'org.json:json:20160212'
  implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_jdk8_version"

  // http://kong.github.io/unirest-java/#requests
  implementation group: 'com.konghq',
              name: 'unirest-java',
              version: '3.7.04',
              classifier: 'standalone'

  // jjwt is for generating and dealing with JWTs
  // jose is for dealing with JWKs (not supported yet in jjwt)
  // b_c is also for JWTs, and I should replace it with nimbus.
  implementation "com.nimbusds:nimbus-jose-jwt:8.19"
  implementation "org.bitbucket.b_c:jose4j:0.7.2"
  implementation "io.jsonwebtoken:jjwt-api:0.11.2"
  runtimeOnly "io.jsonwebtoken:jjwt-impl:0.11.2"
  runtimeOnly "io.jsonwebtoken:jjwt-gson:0.11.2"

  implementation 'org.redisson:redisson:3.13.2'  

  implementation 'com.google.api-client:google-api-client:1.30.10'
}

compileJava {
  options.compilerArgs << '-Xlint:deprecation'
}

compileKotlin {
    doFirst {
      destinationDir = compileJava.destinationDir
    }
}

jar {
    duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}

// Force Kotlin compiler to pick up Kotlin files in src/main/java.
sourceSets {
    main.java.srcDirs += "src/main/java"
}

// WARNING:  Some Gradle issue going on here.
// Sometimes you need to comment out this configuration here, rebuild, make sure
// Authenticator.class is in ./build/libs/wyvern-auth-1.1.jar, and then comment it
// back in to create and publish the sources jar and correct classes jar.
java {
  // IntelliJ can also use the sources jar, published to the same location.
  withSourcesJar()
}

publishing {
    publications {
        mavenJava(MavenPublication) {
            groupId 'my.group.id'
            artifactId 'my-submodule'
            version "$version"
            from components.java
        }
    }
}

publishing {
    repositories {
        maven {
            url "$buildDir/repo"
        }
    }
}

// Automatically publishes the jar to ~/.m2 for Maven when you "gradle build".
jar.finalizedBy publishToMavenLocal
publishToMavenLocal.onlyIf { jar.didWork }
buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

Would love to know what I’m doing wrong, if anyone has ideas. Thank you.

1 Like

A few days ago I moved my kotlin code from src/main/java over to src/main/kotlin, and that seems to have resolved the issue. Just thought I’d follow up in case anyone else runs into this.

Scratch that; it’s back. If anyone actually cares about this bug, I would be happy to send you the entire source code to this submodule.

Just guessing here: Are you running any other task before invoking pushToMavenLocal? It might be that the pushToMavenLocal does not actually generate the resulting jar itself but some other build* task. To investigate I recommend to delete the respective folder in ~/.m2/repository/com/example/ and only invoke ./gradlew clean pushToMavenLocal.

Perhaps your tasks aren’t wired together correctly. Try adding the task tree plugin to your build.

plugins {
    id "com.dorongold.task-tree" version "1.5"
}

Then run

gradle pushToMavenLocal taskTree 

Then you’ll see the tree of tasks