How do I download a single Maven artifact to a folder?

Hi

Quite new on Gradle and Kotlin, I am working on a Kotlin deployement script which is intended to pick a bootable JAR archive (stored in a Maven repository) and to build a Docker image with it.
So, the first step is, in brief:
I want to: copy a jar archive referenced via groupId + artifactId + version, stored in a Maven repository, either local or distant to a sub-directory of the project build folder
So that: I can use it to create a Docker image

All of the examples I saw on the Internet are written in Groovy and I am struggling to translate them, especially the answer of @Chris_Dore here: How to use Gradle to download artifacts in a script?
​Currently, what I have is:

plugins {
   ​java
}

val myDownloads: Configuration by configurations.creating
myDownloads.isTransitive = false

dependencies {
   ​myDownloads(
       ​group = "com.x.y",
       ​name = "myApp",
       ​version = "1.0-03ed0dc"
   ​)
}

val downloadFromRepository = tasks.register<Copy>("downloadFromRepository") {
  ​​from(configurations.getByName("myDownloads"))
  ​​into("${project.buildDir}/app")
}
repositories { (...) }

This works well, except that it does not copy anything. When I execute ./gradlew dependencies, the output is:

> Task :dependencies
------------------------------------------------------------
Root project 'test'
------------------------------------------------------------
annotationProcessor - Annotation processors and their dependencies for source set 'main'.
No dependencies
(...)
myDownloads
\--- com.x.y:myApp:0.1.0-03ed0dc
(...)

It seems obvious that I am doing something wrong, could someone help me to find what I have to code to make it work?

Thanks in advance for taking time reading me
Éric

Are you sure your dependency actually has a jar?
While I would refactor your code a bit, it works perfectly fine for me with a dependency that actually has a jar.

Here the refactored version if you are curious, the removed java plugin is part of the refactoring as you don’t use anything from it:

val myDownloads by configurations.creating {
    isTransitive = false
}

dependencies {
    myDownloads("com.x.y:myApp:1.0-03ed0dc")
}

val downloadFromRepository by tasks.registering(Copy::class) {
    from(myDownloads)
    into(layout.buildDirectory.dir("app"))
}

repositories { /* ... */ }

And if you know your jar does not define any dependencies anyway, you can even leave out the isTransitive = false.

Hi Björn

I’m not sure I understood your question…
In fact, the artifact com.x.y:myApp:1.0-03ed0dc is built in another project and has dependencies. But I am not interessed in these, what I need is myApp-1.0-03ed0dc.jar file :slight_smile:

The question was, whether the myApp-1.0-03ed0dc.jar file is really present and the metadata file is correct.
As I said, I tested with a different dependency and it worked perfectly fine.

Yes, the jar file is present on my local repository, as shown by ./gradlew dependencies result. If it wasn’t, I would have a FAILED flag on the line.
Did you guess that it could be related to the nature of the jar itself, as it is a SpringBoot jar whose content has been modified? I will try with a classical jar file such as Slf4J

Regarding the metadata.xml file, it is generated via `maven-publish:

publishing {
    publications {
        create<MavenPublication>("myApp") {
            from(components["java"])
			
            // Spring bootjar should be published too
            artifact( tasks.getByName("bootJarWithDocs") )

            // artifactId is left by default, groupID and version are defined in lines above

            pom {
                developers {
					(...)
                }
                scm {
					(...)
                }
            }
            versionMapping {
                usage("java-api") {
                    fromResolutionOf("runtimeClasspath")
                }
                usage("java-runtime") {
                    fromResolutionResult()
                }
            }
        }
    }
    repositories {
        maven {
            name = "Nexus"
            (...)
        }
    }
}

OK, Björn, that’s it. Using a reference to a classical jar makes the script work as intended (as you said earlier).
So now, I would like to know why the jar repackaged by SpringBoot to make it bootable is not picked up with the same code…
I don’t know if it could be related to bad metadata.xml file as the working example do not own such a file in its directory tree…

Ok, got it !

Deleting the myApp-0.1.0-03ed0dc.module file which is published via the maven-publish plugin makes the SpringBoot jar downloadable. I have to find how to configure that :slight_smile:

Many thanks for your answers, Björn, and for highlighting the point which makes us solves this case :+1:
Éric

1 Like