How to automatically check dependency licenses in Gradle projects using Gradle License Report
Learn how to perform an automatic license check on your Gradle dependencies and avoid having bigger troubles because of license infringement.

In software development, it’s not uncommon to introduce a new dependency to a project to solve a specific problem. And it is easy and common to forget to check the license of the dependency you are adding to your project. But forgetting it might cause a lot of trouble to you and your company. For instance, you might unknowingly add a library that has an AGPL license, which demands you to disclose and distribute your full source code and make it open source. You or your company might not be willing to do such a thing with your commercial, closed-source project. Not complying with the terms of the license, you and your company can easily run into legal issues because of software license infringement. Fortunately, there’s a plugin called “Gradle License Report” that can prevent having legal issues and save us time by automatically comparing the licenses of the dependencies to the set of licenses you or your company allows. This automated task can also be easily integrated into your CI pipeline and be potentially applied as a company-wide solution.
Goal
Our goal by using this plugin is to add an additional step to our ./gradlew check
task — which comes as a part of Gradle Java plugin — that will go through each of our dependencies and compare their licenses with the set of licenses that we allow in our project.
Let’s Get Started!
We can start using it by simply adding the following to our build.gradle
file:
plugins {
id 'com.github.jk1.dependency-license-report' version '1.16'
}
Then, we need to create a file allowed-licenses.json
in the following format, which will contain the set of licenses we allow. For simplicity, we only have Apache License, Version 2.0, and Eclipse Public License v1.0 in our list.
{
"allowedLicenses": [
{
"moduleLicense": "Apache License, Version 2.0"
},
{
"moduleLicense": "Eclipse Public License - v1.0"
}
]
}
License Normalizer
We also need to use a normalizer, which normalizes the license names written in different variations. For instance, one dependency’s license might be specified as Apache License Version 2.0
, and another one might be Apache License, Version 2.0
. Without a normalizer, we would have to add each of these two to our allowed-licenses.json
file separately, although they imply the same license. Therefore, using a normalizer saves us from having redundancy issues and allows us to maintain a cleaner allowed licenses list.
To do so, we need to create a new JSON file license-normalizer-bundle.json
in which we can specify our transformation rules based on license name, license URL, and license file content, in the following format:
{
"bundles": [
{
"bundleName": "Apache-2.0",
"licenseName": "Apache License, Version 2.0",
"licenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},
{
"bundleName": "EPL-1.0",
"licenseName": "Eclipse Public License - v 1.0",
"licenseUrl": "http://www.eclipse.org/legal/epl-v10.html"
}
],
"transformationRules": [
{
"bundleName": "Apache-2.0",
"licenseNamePattern": ".*The Apache Software License, Version 2\\.0.*"
},
{
"bundleName": "Apache-2.0",
"licenseNamePattern": "Apache[ |-|_]2.*"
},
{
"bundleName": "Apache-2.0",
"licenseNamePattern": "ASL 2\\.0"
},
{
"bundleName": "Apache-2.0",
"licenseNamePattern": ".*Apache License,?( Version)? 2.*"
},
{
"bundleName": "Apache-2.0",
"licenseUrlPattern": ".*(www\\.)?opensource\\.org/licenses/Apache-2\\.0.*"
},
{
"bundleName": "Apache-2.0",
"licenseUrlPattern": ".*www\\.apache\\.org/licenses/LICENSE-2\\.0.*"
},
{
"bundleName": "Apache-2.0",
"licenseFileContentPattern": ".*Apache License,?( Version)? 2.*"
},
{
"bundleName": "EPL-1.0",
"licenseNamePattern": "Eclipse Public License.*(v|version)\\.?\\s?1(\\.?0)?"
}
]
}
In the normalizer example above, bundles
list defines how the normalized license names and URLs should look, and transformationRules
list contains the transformation rules defined for our bundles. The items in bundles
and transformationRules
are matched based on bundleName
. As a starting point, you can use default-license-normalizer.bundle.json
provided in the plugin’s GitHub repository, which normalizes a set of frequently used licenses.
Configuring build.gradle
And lastly, we need to do some additional configurations in our build.gradle
file:
check {
dependsOn checkLicense
}import com.github.jk1.license.filter.LicenseBundleNormalizer
import com.github.jk1.license.render.CsvReportRendererapply plugin: 'com.github.jk1.dependency-license-report'licenseReport {
configurations = ALL
allowedLicensesFile = new File("$projectDir/config/allowed-licenses.json")
filters = [new LicenseBundleNormalizer(bundlePath: "$projectDir/config/license-normalizer-bundle.json")]
renderers = [new CsvReportRenderer()]
}
With the configurations above, we make check
task depend on checkLicense
task that comes with Gradle License Report plugin. By setting configurations
to ALL
, license check will be done for all types of dependencies, including test dependencies. We need to specify the paths for the JSON files that we just created using allowedLicensesFile
and filters
fields. In this example, it is assumed allowed-licenses.json
and license-normalizer-bundle.json
are placed in a folder named config
located in the project’s root folder, so make sure to adjust the paths according to your project structure.
Report Renderer
As you might have noticed, we also added a CSV report renderer to our configuration, which is useful when generating a license report from our dependencies. To generate a license report, you can simply run ./gradlew generateLicenseReport
. The result will be available as a CSV, in your build/reports
folder. You can also use other types of renderers, such as SimpleHtmlReportRenderer
, JsonReportRenderer
etc.
In Action
And that was all we had to do with our project to configure the license checker. When you run ./gradlew check
or any task that depends on check
, license check will be performed automatically via checkLicense
, and if the license check fails, check
task will fail because of checkLicense
task.

The set of dependencies that caused checkLicense
to fail will become available in dependencies-without-allowed-license.json
file located in build/reports
folder, so that you can take a look and see if you want to do some adjustments.
And that’s it! As a side note, if you want to know more about what the licenses of your dependencies actually mean without getting lost in the legal language, I would recommend tldrlegal.com.
Thank you for reading my first Medium article! Please let me know if you have any questions or any feedback in the responses section.