This past week I came across a page in the Google developer documentation for a new plugin and related library in Google Play services for Including Open Source Notices.
Displaying open source notices is certainly important, but it also tends to be a tedious and sometimes painful process so I was intrigued by the promise of a simplified workflow that could nearly automate the process.
I decided to give it a quick try. Quick is an appropriate term here, because It really did take only a few minutes to get a working example up and running to quickly evaluate the new tools.
I’ll explain how I made my evaluation below, but the tl;dr is … this is probably not the tool you are looking for. Unless all the libraries you’re using have the correct license info included in the POM (they probably all don’t), you’re most likely going to want to find a different solution
This is not the tool you’re looking for…probably.
Setup
This new set of tools includes 2 components:
- A plugin that parses your dependencies’ POM file and looks for license info
- A library that includes an
OssLicensesMenuActivity
that will display the parsed license info
The setup for incorporating these new tools can be found here and is quite straightforward:
- Update root-level
build.gradle
file
- Make sure the Google maven repository is defined
maven { url "https://maven.google.com" } // or google() for Gradle 4+
- Add
oss-licenses
plugin to the dependenices section classpath com.google.gms:oss-licenses:0.9.0
2. Update app-level build.gradle
file
- Apply the plugin by adding the following line:
apply plugin: 'com.google.gms.oss.licenses.plugin'
- Declare the library dependency:
compile 'com.google.android.gms:play-services-oss-licenses:11.2.2'
Once this is done, rebuild your project and you should see 2 new files added
- `src/main/res/raw/third_party_license_metadata`: contains a list of dependency names
- `src/main/res/raw/third_party_licenses`: contains a list of license urls
Usage
To display the license info within your app, simply start the provided Activity
class
startActivity(new Intent(this, OssLicensesMenuActivity.class));
Does it work?
For this set of dependencies
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar']) implementation"org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" implementation 'com.android.support:appcompat-v7:26.0.2'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
implementation 'com.android.support:design:26.0.2'
implementation 'com.google.android.gms:play-services-oss-licenses:11.2.2' testImplementation 'junit:junit:4.12'
androidTestImplementation('com.android.support.test.espresso:espresso-core:3.0.1', {
exclude group: 'com.android.support', module: 'support-annotations'
})
}
the started Activity
will look something like this:
For this small set of dependencies the plugin seems to do pretty well. There are 10+ license items included in this list, and clicking on an item displays the url for the license text file. (It would be nice if the license url was clickable, but it’s certainly better than nothing)
Since most projects are going to have more than a handful of dependencies, I added some additional items to my dependencies section and redeployed to see the results.
With this updated set of dependencies
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" implementation 'com.android.support:appcompat-v7:26.0.2'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
implementation 'com.android.support:design:26.0.2'
implementation 'com.google.android.gms:play-services-oss-licenses:11.2.2' implementation 'com.facebook.device.yearclass:yearclass:2.0.0'
implementation 'com.squareup.moshi:moshi-kotlin:1.5.0'
implementation 'com.google.code.gson:gson:2.8.1' implementation 'uk.co.chrisjenx:calligraphy:2.3.0'
implementation 'com.birbit:android-priority-jobqueue:2.0.1'
implementation 'io.reactivex:rxjava:1.3.0' implementation 'com.squareup.retrofit2:retrofit:2.2.0'
implementation 'com.squareup:otto:1.3.8' implementation 'com.google.android.exoplayer:exoplayer:r1.5.16' testImplementation 'junit:junit:4.12'
androidTestImplementation('com.android.support.test.espresso:espresso-core:3.0.1', {
exclude group: 'com.android.support', module: 'support-annotations'
})
}
The resulting license list is certainly longer
but… it doesn’t include everything I would expect. There were no items for some of the libraries such as retrofit, moshi, or exoplayer.
I tried out this same approach on a production project, and the number of missing dependencies was even greater. This discrepancy is why I don’t think this is a valid solution right now for including open source dependencies. If you can’t trust that everything will be included, then, in my opinion, you’re better off handling it all manually to ensure you don’t miss anything.
If you try it out, and everything seems to be in order then by all means use these tools. They’re easy enough to quickly try and validate, but you would need to be sure to revalidate the parsed license data each time you add a dependency.
Alternatives
If your set of dependencies isn’t completed covered by these tools, what are your options?
Probably the most straightforward approach is to simply roll your own solution to display info for the licenses you add.
Pros
- Full control of UI/UX
- Full control of what is added (or missing)
Cons
- Tedious
- Time consuming
Since it’s an open source problem, it would be nice to have an open source solution as well. There are a couple solutions I’ve come across that could be a good starting point
Try it yourself
I encourage you to try these tools out in your own project, but if you want to start on something smaller you can check out my sample code here
Follow Us
For more from the engineers and data scientists building Udacity, follow us here on Medium.
Interested in joining us @udacity? See our current opportunities.