Collecting licenses used in a gradle project
Last year I wrote a post about updating the dependencies in a gradle project. I didn’t want to setup someething heavy like dependabots, so I’d ended up writing a quite script. Last week, I wanted to collect more informations about those dependencies, specifically under which licenses those libraries were published.
I usually try to weight the pros and cons before adding a dependency in my project. There is a bunch of factors that come into play and the license is definitely one of them. To be totally transparent, I don’t pretend to understand the differences between all those licenses and their different versions, but I try to stay away from the scary ones. I don’t want top spoil the the ending of this post, but it wasn’t really surprising to see that most of the licenses in my projects were either Apache 2.0 or MIT. Anyway, let’s carry on.
One of the (legitimate) question you might ask yourself is why I ended up writing code for this instead of using some AI Agent or looking for a tool that already existed. Well, I actually started with the later. I did find a gradle plugin that seemed to do exactly what I wanted. I tried to set it up in my project and because it didn’t work immediately, I lost patience almost immediately. For something I would probably want to do once or twice, learning how to use this plugin wasn’t worth my time. I’m not throwing shade at this existing project since it seems very powerful: you can have different renderer (a CSV, an HTML file…) and even add rule to prevent libraries using a specific license to be added to your project. Very convenient, but way overkill for my needs.
Instead, I piggybacked on my previous script that parses the version catalog file in my project and for each version of a dependency, I attempted to grab the associated pom.xml file (example here). What’s interesting with this appraoch is that the associated pom.xml file may contain informations about the licenses used (pom.xml reference file).
So, once I had the file, I just had a XML file to parse:
val document = DocumentBuilderFactory.newInstance().apply {
// Some settings ...
}.newDocumentBuilder().parse(pomXmlContent)
val licenseNodes = document.getElementsByTagName("license")
val licenses = (0 until licenseNodes.length).mapNotNull { index ->
val license = licenseNodes.item(index) as Element
val name = license.getElementsByTagName("name").item(0)?.textContent ?: return@mapNotNull null
License(name)
}
I also cleaned up the original script that checked for outdated dependencies so I could reuse most of it (parsing the version catalog, grabbing the version it was using…). I also wrapped those 2 actions (checking dependencies and collecting licenses) in separate classes using Clikt.
The result is a pretty straitforward command line tool that can be ran via IntelliJ or a target in my Makefile, but there are some limitations. For starters, a few of my dependencies did not publish a pom.xml so I ended up having to check manually online. Additionally, there is a little bit of noise because some licenses are written as “Apache-2.0” while some others used “The Apache Software License, Version 2.0”. There is also some duplicates since I’m using a bunch of the ktor server or client components, which are all published under the same license. Nothing worth fixing right now. Plus, I already had my fun.