This plugin provides a task to generate a HTML license report based on the configuration. (eg. licenseDebugReport for
all debug dependencies in an Android project).
Applying this to an Android or Java project will generate the license reports in
<project>/build/reports/licenses/, named after the task that produced them - licenseReport.html
for a Java project, licenseDebugReport.html for an Android debug variant, and so on. CSV, HTML, JSON and text reports
are generated by default.
Also, for Android projects the reports are copied into the asset directory of the variant that produced them -
<project>/src/debug/assets/, <project>/src/release/assets/ and so on - and it is only there that they are named
open_source_licenses.<ext>. Every variant gets its own, so a debug build cannot ship a release build's report.
| Plugin Version | Minimum Gradle Version | Minimum AGP Version |
|---|---|---|
| <= 0.9.4 | <= 7.0.2 | 3.6.4+ |
| 0.9.5 | 7.0.2 | 3.6.4+ |
| 0.9.6 | 7.1.3 | 3.6.4+ |
| 0.9.7 | 7.2.2 | 3.6.4+ |
| 0.9.8 | 7.2.2 | 3.6.4+ |
| 0.9.9 | 8.2 | 8.0.0+ |
| 0.9.91 | 8.2 | 8.0.0+ |
Note:
0.9.9+requires JDK 17+. AGP 9.x additionally requires a newer Gradle than the minimum above, and how much newer depends on the AGP version rather than being a single number - AGP 9.0 needs Gradle 9.1+ and AGP 9.2 needs Gradle 9.5+ (both are AGP requirements, not this plugin's).
Release:
with plugins { }
plugins {
id("com.jaredsburrows.license") version "0.9.91"
}with buildscript { }
buildscript {
repositories {
mavenCentral()
google() // For Android projects
}
dependencies {
classpath("com.jaredsburrows:gradle-license-plugin:0.9.91")
}
}
apply(plugin = "com.android.application") // or "java-library"
apply(plugin = "com.jaredsburrows.license")Release versions are available in the Sonatype's release repository and here.
Snapshot:
with plugins { }
plugins {
id("com.jaredsburrows.license") version "0.10.0-SNAPSHOT"
}with buildscript { }
buildscript {
repositories {
maven { url = uri("https://central.sonatype.com/repository/maven-snapshots/") }
google() // For Android projects
}
dependencies {
classpath("com.jaredsburrows:gradle-license-plugin:0.10.0-SNAPSHOT")
}
}
apply(plugin = "com.android.application") // or "java-library"
apply(plugin = "com.jaredsburrows.license")Snapshot versions are available in the Central Portal snapshots repository.
licenseReportfor Java and Kotlin JVMlicense${variant}Reportfor Androidlicense${target}Reportfor Kotlin Multiplatform
Generates a report of all the open source licenses. (eg. licenseDebugReport for all debug dependencies in an Android
project).
An Android project gets one task per variant, plus one for each of the variant's test components -
licenseDebugReport, licenseReleaseReport, licenseDebugUnitTestReport and so on.
A Kotlin Multiplatform project gets one task per target - licenseJvmReport, licenseJsReport,
licenseLinuxX64Report. The common (metadata) target resolves no dependencies of its own and is skipped. A
multiplatform module that also applies an Android plugin gets both: its android target is reported per variant by the
Android tasks above, and every other target gets its own task. For a module using AGP's multiplatform library plugin
that is licenseAndroidMainReport.
Example build.gradle.kts:
dependencies {
implementation("com.android.support:design:26.1.0")
implementation("pl.droidsonroids.gif:android-gif-drawable:1.2.3")
implementation("wsdl4j:wsdl4j:1.5.1") // Very old library with no license info available
}CSV Example (full):
project,description,version,developers,url,year,licenses,license urls,dependency
Android GIF Drawable Library,Views and Drawable for displaying animated GIFs for Android,1.2.3,Karol Wrótniak,https://github.com/koral--/android-gif-drawable,null,The MIT License,http://opensource.org/licenses/MIT,pl.droidsonroids.gif:android-gif-drawable:1.2.3
design,null,26.1.0,null,null,null,The Apache Software License,http://www.apache.org/licenses/LICENSE-2.0.txt,com.android.support:design:26.1.0HTML Example (license descriptions are minimized):
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<style>body {
font-family: sans-serif
}
pre {
background-color: #eeeeee;
padding: 1em;
white-space: pre-wrap;
word-break: break-word;
display: inline-block
}</style>
<title>Open source licenses</title>
</head>
<body>
<h3>Notice for packages:</h3>
<ul>
<li><a href="#1934118923">design</a>
<dl>
<dt>Copyright © 20xx The original author or authors</dt>
<dd></dd>
</dl>
</li>
</ul>
<pre id="1934118923">apache-2.0.txt here</pre>
<br>
<hr>
<ul>
<li><a href="#1783810846">Android GIF Drawable Library</a>
<dl>
<dt>Copyright © 20xx Karol WrXXtniak</dt>
<dd></dd>
</dl>
</li>
</ul>
<pre id="1783810846">apache-2.0.txt here</pre>
<br>
<hr>
</body>
</html>Note, if no license information is found in the POM for a project, "No License Found" will be used. Those will be listed first. Other missing information is provided as default values that can be corrected from other sources. Projects are grouped by license name and the license text is only provided once. Projects with multiple licenses are grouped as if those licenses were a single combined license.
JSON Example (full):
[
{
"project": "Android GIF Drawable Library",
"description": "Views and Drawable for displaying animated GIFs for Android",
"version": "1.2.3",
"developers": [
"Karol Wr\\u00c3\\u00b3tniak"
],
"url": "https://github.com/koral--/android-gif-drawable",
"year": null,
"licenses": [
{
"license": "The MIT License",
"license_url": "http://opensource.org/licenses/MIT"
}
],
"dependency": "pl.droidsonroids.gif:android-gif-drawable:1.2.3"
},
{
"project": "design",
"description": null,
"version": "26.1.0",
"developers": [],
"url": null,
"year": null,
"licenses": [
{
"license": "The Apache Software License",
"license_url": "http://www.apache.org/licenses/LICENSE-2.0.txt"
}
],
"dependency": "com.android.support:design:26.1.0"
}
]Note, if no license information is found for a component, the licenses element in the JSON output will be an empty
array.
Full JSON Example (full):
Each license text is stored once under license_texts and referenced by license_key, so a report covering dozens of
dependencies that share a handful of licenses stays small.
{
"license_texts": {
"apache-2.0": "Apache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/ ...",
"mit": "MIT License\n\nCopyright (c) [year] [fullname]\n\nPermission is hereby granted, free of charge, ..."
},
"dependencies": [
{
"project": "Android GIF Drawable Library",
"description": "Views and Drawable for displaying animated GIFs for Android",
"version": "1.2.3",
"developers": [
"Karol Wr\\u00c3\\u00b3tniak"
],
"url": "https://github.com/koral--/android-gif-drawable",
"year": null,
"licenses": [
{
"license": "The MIT License",
"license_url": "http://opensource.org/licenses/MIT",
"license_key": "mit"
}
],
"dependency": "pl.droidsonroids.gif:android-gif-drawable:1.2.3"
},
{
"project": "design",
"description": null,
"version": "26.1.0",
"developers": [],
"url": null,
"year": null,
"licenses": [
{
"license": "The Apache Software License",
"license_url": "http://www.apache.org/licenses/LICENSE-2.0.txt",
"license_key": "apache-2.0"
}
],
"dependency": "com.android.support:design:26.1.0"
}
]
}Note, license_key is null for licenses that are not bundled with the plugin - license and
license_url always hold what the POM declared, so use those for the ones without a text.
Text Example (full):
Notice for packages
Android GIF Drawable Library (1.2.3) - The MIT License
Views and Drawable for displaying animated GIFs for Android
https://github.com/koral--/android-gif-drawable
design (26.1.0) - The Apache Software License
The plugin can be configured to generate specific reports and automatically copy the reports to the assets directory (Android projects only). The default behaviours are:
- Java projects: Generate CSV, HTML, JSON and text reports.
- Android projects: Generate CSV, HTML, JSON and text reports, and copy the HTML report to the assets directory.
The plugin can be configured to ignore licenses for certain artifact patterns. The default is that nothing is ignored.
To override the defaults, add the licenseReport configuration closure to the build script.
plugins {
id("com.jaredsburrows.license")
}
licenseReport {
// Generate reports
generateCsvReport = false
generateHtmlReport = true
generateJsonReport = false
generateJsonFullReport = false
generateTextReport = false
// Copy reports - These options are ignored for Java projects
copyCsvReportToAssets = false
copyHtmlReportToAssets = true
copyJsonReportToAssets = false
copyJsonFullReportToAssets = false
copyTextReportToAssets = false
useVariantSpecificAssetDirs = true
// Ignore licenses for certain artifact patterns
ignoredPatterns = setOf()
// Show versions in the report - default is false
showVersions = true
}Note: the
licenseReport { }accessor exists only when the plugin is applied throughplugins { }. If you applied it thebuildscript { }way withapply(plugin = ...), configure it by type instead:import com.jaredsburrows.license.LicenseReportExtension configure<LicenseReportExtension> { generateCsvReport = false }
The copyHtmlReportToAssets option in the above example would have no effect since the HTML report is disabled.
The generateJsonFullReport option generates open_source_licenses.full.json, the JSON report plus the full text of
every license the plugin knows about. It is meant for applications that render their own license screen instead of
displaying the generated HTML report, so the license text ships with the app and no network call or WebView is needed.
It is disabled by default because the license texts make the report larger.
Every license text is stored once under the top level license_texts, keyed by license id, and each dependency
references it with license_key. Dependencies overwhelmingly share a handful of licenses, so this keeps the report -
and the memory an app needs to parse it - roughly an order of magnitude smaller than repeating the text per dependency.
The useVariantSpecificAssetDirs copies the reports into the source set asset directory of the variant that produced
them, which is the default. For example, licensePaidProductionReleaseReport puts its reports in
src/paidProductionRelease/assets. Each variant therefore keeps its own report, and the path inside the built APK or
AAR is unchanged - still assets/open_source_licenses.<ext>.
Setting it to false sends every variant's report to src/main/assets instead. That is a single shared file, so
whichever report task runs last wins and a build can ship another variant's licenses
(#226). It was the default before 0.10.0; only
set it if you have one variant, or you are relying on the old path and accept that risk.
The ignoredPatterns allows for ignoring artifact patterns. A pattern can cover whole segments of the
group:artifact:version coordinate (a group, an artifact, a version, or any combination), but it only matches along
segment boundaries: ignoring com.some.group:some.name does not ignore
com.some.group:some.name-extra. Both : and . count as boundaries, so a pattern may also cover dot-separated pieces
of a group or version - 1.2 still ignores version 1.2.3.
plugins {
id("com.jaredsburrows.license")
}
licenseReport {
ignoredPatterns = setOf("com.some.group") // Ignores all artifacts of the given group
ignoredPatterns = setOf("com.some.group:some.name") // Ignores the given artifact regardless of version
ignoredPatterns = setOf("com.some.group:some.name:1.2.3") // Ignores the given artifact with the given version
}For complete, buildable examples - including license screens built from the JSON reports instead of a WebView -
see Test Apps.
import android.webkit.WebView
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.viewinterop.AndroidView
@Composable
fun OpenSourceLicensesDialog(onDismiss: () -> Unit) {
AlertDialog(
onDismissRequest = onDismiss,
title = { Text("Open Source Licenses") },
text = {
AndroidView(
factory = { context ->
WebView(context).apply {
loadUrl("file:///android_asset/open_source_licenses.html")
}
},
)
},
confirmButton = {
TextButton(onClick = onDismiss) {
Text("OK")
}
},
)
}var showLicenses by remember { mutableStateOf(false) }
Button(onClick = { showLicenses = true }) {
Text("Licenses")
}
if (showLicenses) {
OpenSourceLicensesDialog(onDismiss = { showLicenses = false })
}| Type | License Screen | License Details |
|---|---|---|
| HTML | ![]() |
|
| JSON | ![]() |
|
| JSON Full | ![]() |
![]() |
test-apps/ holds three Jetpack Compose applications that apply the plugin from this repository (through
an included build) and show a different way of surfacing the licenses:
| Module | Report | Screen |
|---|---|---|
test-app-compose-html |
open_source_licenses.html |
The generated HTML full screen in a WebView |
test-app-compose-json |
open_source_licenses.json |
A Compose list linking out to each license URL |
test-app-compose-fulljson |
open_source_licenses.full.json |
A custom Compose license screen rendering the bundled license text offline |
Each app generates its report and copies it into its variant source set as part of assemble, so building them
exercises the plugin end to end:
./gradlew -p test-apps buildCopyright (C) 2016 Jared Burrows
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.



