Skip to content

License Scanning doesn't handle gradle dependencies defined using implementation directive

Problem to solve

The following build.gradle file will result in no licenses found:


apply plugin: 'java'
apply plugin: 'maven'
apply plugin: 'maven-publish'

sourceCompatibility = 11
targetCompatibility = 11

repositories {
    mavenCentral()
    mavenLocal()
}

dependencies {
    implementation 'org.slf4j:slf4j-api:1.7.30'
    implementation 'org.slf4j:slf4j-simple:1.7.30'
    implementation('com.fasterxml.jackson.core:jackson-core:2.11.1')
    implementation('com.fasterxml.jackson.core:jackson-databind:2.11.1')
    implementation('com.fasterxml.jackson.core:jackson-annotations:2.11.1')
    testImplementation 'org.junit.jupiter:junit-jupiter:5.6.2'
}

This is because the above dependencies block uses the implementation directive. In order to retrieve licences, dependencies must instead use the compile directive:

dependencies {
-    implementation 'org.slf4j:slf4j-api:1.7.30'
-    implementation 'org.slf4j:slf4j-simple:1.7.30'
-    implementation('com.fasterxml.jackson.core:jackson-core:2.11.1')
-    implementation('com.fasterxml.jackson.core:jackson-databind:2.11.1')
-    implementation('com.fasterxml.jackson.core:jackson-annotations:2.11.1')
+    compile 'org.slf4j:slf4j-api:1.7.30'
+    compile 'org.slf4j:slf4j-simple:1.7.30'
+    compile('com.fasterxml.jackson.core:jackson-core:2.11.1')
+    compile('com.fasterxml.jackson.core:jackson-databind:2.11.1')
+    compile('com.fasterxml.jackson.core:jackson-annotations:2.11.1')
    testImplementation 'org.junit.jupiter:junit-jupiter:5.6.2'
}

Implementation Plan

  1. Create a gradle integration test which demonstrates the described bug. This should probably be added to spec/integration/java/gradle_spec.rb, but this needs to be confirmed.
  2. Add a gradle init script to license-finder which can be executed at scan time to set the dependency configuration runtimeClasspath by default - this works for both compile and implementation
  3. Additionally update the init script so that the dependency configuration can be supplied to the analyzer via environment variable.
  4. Update the tests with cases applying the init script and configuring the dependencyConfiguration directive.

Tested init script which works:

./gradlew  --init-script init.gradle downloadLicenses

init.gradle:

initscript {
  repositories {
    maven {
      url "https://plugins.gradle.org/m2/"
    }
  }

  dependencies {
    classpath 'gradle.plugin.com.hierynomus.gradle.plugins:license-gradle-plugin:0.15.0'
  }
}

allprojects {
  apply plugin: "java"
  apply plugin: com.hierynomus.gradle.license.LicenseReportingPlugin
  downloadLicenses {
    dependencyConfiguration = 'runtimeClasspath'
  }

}

Generated licenses are in build/reports/license.

User experience goal

Current license scanning limitation is resolved or documented.

Further details

This will solve issues such as the one described in License Scanning reports no license for some complex Gradle projects

What does success look like?

License scanning should be able to display licenses for packages defined using an implementation directive, or this shortcoming should be documented with a workaround provided.

What is the type of buyer?

GitLab Ultimate Enterprise Edition

Is this a cross-stage feature?

No, this only affects ~"Category:License Compliance"

/cc @gonzoyumo @NicoleSchwartz

Edited by Oscar Tovar