Need help with building an executable jar that can be published to maven local repo with `publishToMavenLocal` - spring boot project

Need help with building an executable jar (that can be run with java -jar app.jar) that can be published to maven local repo (using gradle publishToMavenLocal) for a spring boot project.

With these gradle settings gradle publishToMavenLocal works.

Gradle version is 6.3
Spring boot version is 2.2.6
Kotlin 1.3.71

parent build.gradle.kts

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

buildscript {
    repositories {
        mavenLocal()
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:2.2.6.RELEASE")
    }
}

plugins {
    id("org.springframework.boot") version "2.2.6.RELEASE" apply false
    id("io.spring.dependency-management") version "1.0.9.RELEASE" apply false
    kotlin("jvm") version "1.3.71" apply false
    kotlin("plugin.spring") version "1.3.71" apply false
    `maven-publish`
    `java-library`
    signing
}

allprojects {
    group = "com.example.user"
    version = "0.0.1-SNAPSHOT"

    tasks.withType<JavaCompile> {
        sourceCompatibility = "1.8"
        targetCompatibility = "1.8"
    }

    tasks.withType<KotlinCompile> {
        kotlinOptions {
            freeCompilerArgs = listOf("-Xjsr305=strict")
            jvmTarget = "1.8"
            incremental = false
        }
    }
}

subprojects {
    repositories {
        mavenLocal()
        mavenCentral()
    }

    apply {
        plugin("io.spring.dependency-management")
        plugin("maven-publish")
    }
}

sub-project build.gradle.kts:

plugins {
    id("org.springframework.boot")
    id("io.spring.dependency-management")
    kotlin("jvm")
    kotlin("plugin.spring")
}


val developmentOnly by configurations.creating
configurations {
    runtimeClasspath {
        extendsFrom(developmentOnly)
    }
}

dependencies {
    implementation(project(":common"))
    implementation(project(":user-models"))
    implementation(project(":user-core"))
    implementation("org.springframework.boot:spring-boot-starter-webflux") {
        exclude(group = "org.springframework.boot", module = "spring-boot-starter-logging")
    }

    implementation("org.springframework.boot:spring-boot-maven-plugin:2.2.6.RELEASE")


    implementation(group = "org.springframework.boot", name = "spring-boot-autoconfigure", version = "2.2.6.RELEASE")
    implementation(group = "org.springframework.boot", name = "spring-boot-starter-parent", version = "2.2.6.RELEASE")

    implementation("org.springframework.boot:spring-boot-configuration-processor:2.2.6.RELEASE")

    implementation("org.projectreactor:reactor-spring:1.0.1.RELEASE")
    implementation("io.projectreactor.kotlin:reactor-kotlin-extensions")
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")


    implementation(group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version = "1.3.5")
    implementation(group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-reactor", version = "1.3.5")
    implementation(group = "org.springframework.boot", name = "spring-boot-starter-log4j2", version = "2.2.6.RELEASE")

    implementation("org.jetbrains.kotlin:kotlin-reflect")
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

    developmentOnly("org.springframework.boot:spring-boot-devtools")

    testImplementation("org.springframework.boot:spring-boot-starter-test") {
        exclude(group = "org.junit.vintage", module = "junit-vintage-engine")
    }

}

tasks.withType<Test> {
    useJUnitPlatform()
}

tasks.jar {
    enabled = true
    manifest {
        attributes["Main-Class"] = "com.subnub.user.service.ServiceApplicationKt"
        attributes["Class-Path"] = configurations.compileClasspath.get().map { it.name }.joinToString(" ")
    }

    from(configurations.compileClasspath.get().map { if(it.isDirectory) it else zipTree(it) })

    duplicatesStrategy = DuplicatesStrategy.INCLUDE

}

tasks.bootJar {
    enabled = false
    archiveClassifier.set("application")
    mainClassName = "com.example.user.service.ServiceApplicationKt"
}


publishing {
    publications {
        create<MavenPublication>("mavenJava") {
            from(components["java"])

            afterEvaluate {
                artifactId = tasks.jar.get().archiveBaseName.get()
            }
        }
    }
}

But the jar that is build with these gradle settings breaks when tried to run

stderr:

➜  example-user git:(master) ✗     java -jar example-service/build/libs/example-service-0.0.1-SNAPSHOT.jar
[INFO ] 2020-04-25 22:18:11.871 [main] ServiceApplicationKt - Starting ServiceApplicationKt on admins-mbp-7 with PID 4663 (/Users/zerocase/personal/startups/example/code/example-user/example-service/build/libs/example-service-0.0.1-SNAPSHOT.jar started by abhishek in /Users/zerocase/personal/startups/example/code/example-user)
[INFO ] 2020-04-25 22:18:11.874 [main] ServiceApplicationKt - No active profile set, falling back to default profiles: default
[ERROR] 2020-04-25 22:18:12.055 [main] SpringApplication - Application run failed
java.lang.IllegalArgumentException: No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.
        at org.springframework.util.Assert.notEmpty(Assert.java:464) ~[example-service-0.0.1-SNAPSHOT.jar:?]
        at org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.getCandidateConfigurations(AutoConfigurationImportSelector.java:173) ~[example-service-0.0.1-SNAPSHOT.jar:?]
        at org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.getAutoConfigurationEntry(AutoConfigurationImportSelector.java:116) ~[example-service-0.0.1-SNAPSHOT.jar:?]
        at org.springframework.boot.autoconfigure.AutoConfigurationImportSelector$AutoConfigurationGroup.process(AutoConfigurationImportSelector.java:396) ~[example-service-0.0.1-SNAPSHOT.jar:?]
        at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorGrouping.getImports(ConfigurationClassParser.java:878) ~[example-service-0.0.1-SNAPSHOT.jar:?]
        at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorGroupingHandler.processGroupImports(ConfigurationClassParser.java:808) ~[example-service-0.0.1-SNAPSHOT.jar:?]
        at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorHandler.process(ConfigurationClassParser.java:779) ~[example-service-0.0.1-SNAPSHOT.jar:?]
        at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:192) ~[example-service-0.0.1-SNAPSHOT.jar:?]
        at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:319) ~[example-service-0.0.1-SNAPSHOT.jar:?]
        at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:236) ~[example-service-0.0.1-SNAPSHOT.jar:?]
        at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:275) ~[example-service-0.0.1-SNAPSHOT.jar:?]
        at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:95) ~[example-service-0.0.1-SNAPSHOT.jar:?]
        at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:706) ~[example-service-0.0.1-SNAPSHOT.jar:?]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:532) ~[example-service-0.0.1-SNAPSHOT.jar:?]
        at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.refresh(ReactiveWebServerApplicationContext.java:66) ~[example-service-0.0.1-SNAPSHOT.jar:?]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747) [example-service-0.0.1-SNAPSHOT.jar:?]
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) [example-service-0.0.1-SNAPSHOT.jar:?]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [example-service-0.0.1-SNAPSHOT.jar:?]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) [example-service-0.0.1-SNAPSHOT.jar:?]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) [example-service-0.0.1-SNAPSHOT.jar:?]
        at com.example.user.service.ServiceApplicationKt.main(ServiceApplication.kt:19) [example-service-0.0.1-SNAPSHOT.jar:?]

I’ve tried the workaround suggested here (https://docs.gradle.org/current/userguide/upgrading_version_6.html#publishing_spring_boot_applications) for publishing bootJar artifact. The jar works fine in this case but,

configurations {
    listOf(apiElements, runtimeElements).forEach {
        it.get().outgoing.artifacts.removeIf { it.buildDependencies.getDependencies(null).contains(tasks.jar) }
        it.get().outgoing.artifact(tasks.bootJar)
    }
}

but then gradle does not allows me to do gradle pTML

➜  example-user git:(master) ✗ gradle pTML
> Task :user-service:publishMavenJavaPublicationToMavenLocal FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':user-service:publishMavenJavaPublicationToMavenLocal'.
> Failed to publish publication 'mavenJava' to repository 'mavenLocal'
   > Artifact example-service-0.0.1-SNAPSHOT.jar wasn't produced by this build.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 1s
16 actionable tasks: 3 executed, 13 up-to-date

Figured out the fix, artifact needed to be defined in the the publications scope.

publishing {
    publications {
        create<MavenPublication>("mavenJava") {
            //from(components["java"]) // <-- this is not required
            artifact(tasks.bootJar.get()) // <-- this is required
        }
    }
}

and slight modified configurations scope (ref):

configurations {
    listOf(apiElements, runtimeElements).forEach {
        // Method #1
        val jar by tasks
        it.get().outgoing.artifacts.removeIf { it.buildDependencies.getDependencies(null).contains(jar) }

        // Method #2
        it.get().outgoing.artifact(tasks.bootJar)
    }
}

Here are some sample implementations of publishing publications.