Make arbitrary artifacts from one subproject available in another

Here is at least one thing, that after many years of Gradle usage, I still have not figured out. It is how to allow arbitrary artifacts from one subproject to be consumed by another subproject via a project dependency.

For starters let’s say in projectB I have

dependencies {
  implementation project(':projectA')
}

Now if projectA is just a normal Java / Groovy / Kotlin subproject then everything obviously just works. But what if subprojectA obtains a JAR via a non-Gradle build. Good examples are including legacy or external Ant/Maven/Make builds that create JARs, assuming that those builds do not publish the JARs in a modern Maven/Ivy repo.

Another example is that projectA builds a GEM and projectB wants to consume it for JRuby purposes into then gems configuration.

Given the above examples, let’s assume that projectA runs a task of which the result is artifacts ending up in build/legacy-lib. How would I go about in the projectA buildscript to add all the JARs from legacy-lib in so that projectB can consume them?

(From the PoV of projectB, projectA is just another subproject that produces artificats - it does not care how projectA builds them)

To answer my own question, I think the following is needed:

apply plugin : 'base' // Provides 'artifacts'

configuration {
  legacyJars
}

task buildLegacyJars {
  // Some task that build the artifacts
}

artifacts {
    legacyJars file("${buildDir}/legacy-jars/jar-one.jar"), {  // Add path to JAR
        builtBy buildLegacyJars // Tell Gradle how to build it.
    }
}

In that way projectB can do

dependencies {
   implementaton project( path : ':projectA', configuration : 'legacyJars' )
}

In a thread I had created when working on the same type of subproject artifact behaviour, there’s some additional discussion on task inputs and dependencies which you may or may not find useful/educational.

1 Like