Publishing metadata for artifact defined in custom plugin

I’m developing a plugin for a programming language that I use. I’d like to be able to publish metadata together with artifacts (e.g. what RedHat release, what version of the compiler, etc.). I was reading up on the topic in the user guide: Publishing a project as module

It seems that I need a “component”, which would describe the variant that’s being produced and use the metadata from that. I can’t find a way to create an object of type SoftwareComponent. I tried the following:

def sv = project.objects.newInstance(SoftwareComponent, "sv")

I get:

class org.gradle.api.component.SoftwareComponent_Decorated cannot be cast to class org.gradle.api.internal.component.SoftwareComponentInternal (org.gradle.api.component.SoftwareComponent_Decorated and org.gradle.api.internal.component.SoftwareComponentInternal are in unnamed module of loader org.gradle.internal.classloader.VisitableURLClassLoader @5eb5c224)

I have the feeling that there’s no public API for doing what I want. I can also be on the completely wrong track. How would I go about implementing metadata for artifacts in a custom plugin?

First, I noticed that I’m running a pretty old Gradle version (7.4.2), so stuff might have changed in the implementation. I’m switching to Gradle 8.6 to see whether this got fixed.

Still the same even after upgrading to Gradle 8.6. I had a look at how the native plugins register components. I haven’t found SoftwareComponentInternal anywhere in the type hierarchy. For example, a C++ library:

Then, this is how it gets created:

The native component factory is:

I don’t see SoftwareComponentInternal anywhere.

I had a deeper look and it seems that this comes from somewhere in the code for Maven publishing. Not all components that are added to the project are used for publishing. For a C++ library, sub-components get defined, which are used for the publishing. The objects are of this type, which does implement SoftwareComponentInternal:

This is probably the line that causes the cast error:

To interface with the Maven publishing plugin, implementing this interface seems to be required.

To create a custom component for publishing, you should use the respective factory as documented at: Customizing publishing

But if what you build is da normal Java artifact to which you just want to add a metadata file to the plublication, you probably just publish the java component as usual and define your additional artifact as variant like the source jar or the javadoc jar are added.

I must have read through those pages a couple of times while trying to wrap my head around the concepts, but somehow I missed the SoftwareComponentFactory. I started implementing internal APIs and managed to get it working, but wasn’t 100% happy. I’ll give the approach on that page a try, thanks!

1 Like

Worked like a charm!

1 Like