Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

./gradlew generateLicenseReport --stacktrace fails with NPE #316

Open
bric3 opened this issue Jun 20, 2024 · 11 comments
Open

./gradlew generateLicenseReport --stacktrace fails with NPE #316

bric3 opened this issue Jun 20, 2024 · 11 comments

Comments

@bric3
Copy link

bric3 commented Jun 20, 2024

On multi-module projects, the generation task fails with an NPE

------------------------------------------------------------
Gradle 8.8
------------------------------------------------------------

Build time:   2024-05-31 21:46:56 UTC
Revision:     4bd1b3d3fc3f31db5a26eecb416a165b8cc36082

Kotlin:       1.9.22
Groovy:       3.0.21
Ant:          Apache Ant(TM) version 1.10.13 compiled on January 4 2023
JVM:          21.0.2 (Amazon.com Inc. 21.0.2+13-LTS)
OS:           Mac OS X 14.5 aarch64
Caused by: java.lang.NullPointerException: Cannot get property 'configurations' on null object
	at com.github.jk1.license.reader.ProjectReader.findConfiguredConfigurations(ProjectReader.groovy:96)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at com.github.jk1.license.reader.ProjectReader.findConfigurationsToScan(ProjectReader.groovy:71)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at com.github.jk1.license.task.ReportTask$_getClasspath_closure1.doCall$original(ReportTask.groovy:51)
	at com.github.jk1.license.task.ReportTask$_getClasspath_closure1.doCall(ReportTask.groovy)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at com.github.jk1.license.task.ReportTask.getClasspath(ReportTask.groovy:50)
	at com.github.jk1.license.task.ReportTask_Decorated.getClasspath(Unknown Source)

I don't understand yet the conditions why this is failing, but for sure the project is null

image

this seems to come from the ReportTasks
image

But the extension is supposed to have the current project and sub-projects

The getClasspath method is called on the ReportTask that was configured on my root project.

image
Full stacktrace
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':generateLicenseReport'.
	at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:38)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
	at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:42)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:331)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:318)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.lambda$execute$0(DefaultTaskExecutionGraph.java:314)
	at org.gradle.internal.operations.CurrentBuildOperationRef.with(CurrentBuildOperationRef.java:80)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:314)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:303)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:463)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:380)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
	at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47)
Caused by: org.gradle.api.internal.tasks.properties.PropertyEvaluationException: Error while evaluating property 'classpath' of task ':generateLicenseReport'.
	at org.gradle.api.internal.tasks.properties.InputParameterUtils.prepareInputParameterValue(InputParameterUtils.java:32)
	at org.gradle.api.internal.tasks.execution.TaskExecution.lambda$visitRegularInputs$1(TaskExecution.java:317)
	at org.gradle.internal.execution.impl.DefaultInputFingerprinter$InputCollectingVisitor.visitInputProperty(DefaultInputFingerprinter.java:103)
	at org.gradle.api.internal.tasks.execution.TaskExecution.visitRegularInputs(TaskExecution.java:315)
	at org.gradle.internal.execution.impl.DefaultInputFingerprinter.fingerprintInputProperties(DefaultInputFingerprinter.java:63)
	at org.gradle.internal.execution.steps.AbstractCaptureStateBeforeExecutionStep.captureExecutionStateWithOutputs(AbstractCaptureStateBeforeExecutionStep.java:109)
	at org.gradle.internal.execution.steps.AbstractCaptureStateBeforeExecutionStep.lambda$captureExecutionState$0(AbstractCaptureStateBeforeExecutionStep.java:74)
	at org.gradle.internal.execution.steps.BuildOperationStep$1.call(BuildOperationStep.java:37)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
	at org.gradle.internal.execution.steps.BuildOperationStep.operation(BuildOperationStep.java:34)
	at org.gradle.internal.execution.steps.AbstractCaptureStateBeforeExecutionStep.captureExecutionState(AbstractCaptureStateBeforeExecutionStep.java:69)
	at org.gradle.internal.execution.steps.AbstractCaptureStateBeforeExecutionStep.execute(AbstractCaptureStateBeforeExecutionStep.java:62)
	at org.gradle.internal.execution.steps.AbstractCaptureStateBeforeExecutionStep.execute(AbstractCaptureStateBeforeExecutionStep.java:43)
	at org.gradle.internal.execution.steps.AbstractSkipEmptyWorkStep.executeWithNonEmptySources(AbstractSkipEmptyWorkStep.java:125)
	at org.gradle.internal.execution.steps.AbstractSkipEmptyWorkStep.execute(AbstractSkipEmptyWorkStep.java:56)
	at org.gradle.internal.execution.steps.AbstractSkipEmptyWorkStep.execute(AbstractSkipEmptyWorkStep.java:36)
	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsStartedStep.execute(MarkSnapshottingInputsStartedStep.java:38)
	at org.gradle.internal.execution.steps.LoadPreviousExecutionStateStep.execute(LoadPreviousExecutionStateStep.java:36)
	at org.gradle.internal.execution.steps.LoadPreviousExecutionStateStep.execute(LoadPreviousExecutionStateStep.java:23)
	at org.gradle.internal.execution.steps.HandleStaleOutputsStep.execute(HandleStaleOutputsStep.java:75)
	at org.gradle.internal.execution.steps.HandleStaleOutputsStep.execute(HandleStaleOutputsStep.java:41)
	at org.gradle.internal.execution.steps.AssignMutableWorkspaceStep.lambda$execute$0(AssignMutableWorkspaceStep.java:35)
	at org.gradle.api.internal.tasks.execution.TaskExecution$4.withWorkspace(TaskExecution.java:289)
	at org.gradle.internal.execution.steps.AssignMutableWorkspaceStep.execute(AssignMutableWorkspaceStep.java:31)
	at org.gradle.internal.execution.steps.AssignMutableWorkspaceStep.execute(AssignMutableWorkspaceStep.java:22)
	at org.gradle.internal.execution.steps.ChoosePipelineStep.execute(ChoosePipelineStep.java:40)
	at org.gradle.internal.execution.steps.ChoosePipelineStep.execute(ChoosePipelineStep.java:23)
	at org.gradle.internal.execution.steps.ExecuteWorkBuildOperationFiringStep.lambda$execute$2(ExecuteWorkBuildOperationFiringStep.java:67)
	at org.gradle.internal.execution.steps.ExecuteWorkBuildOperationFiringStep.execute(ExecuteWorkBuildOperationFiringStep.java:67)
	at org.gradle.internal.execution.steps.ExecuteWorkBuildOperationFiringStep.execute(ExecuteWorkBuildOperationFiringStep.java:39)
	at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:46)
	at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:34)
	at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:48)
	at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:35)
	at org.gradle.internal.execution.impl.DefaultExecutionEngine$1.execute(DefaultExecutionEngine.java:61)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:127)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:116)
	at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
	at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:51)
	at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
	at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:74)
	at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
	at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:42)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:331)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:318)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.lambda$execute$0(DefaultTaskExecutionGraph.java:314)
	at org.gradle.internal.operations.CurrentBuildOperationRef.with(CurrentBuildOperationRef.java:80)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:314)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:303)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:463)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:380)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
	at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47)
Caused by: java.lang.NullPointerException: Cannot get property 'configurations' on null object
	at com.github.jk1.license.reader.ProjectReader.findConfiguredConfigurations(ProjectReader.groovy:96)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at com.github.jk1.license.reader.ProjectReader.findConfigurationsToScan(ProjectReader.groovy:71)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at com.github.jk1.license.task.ReportTask$_getClasspath_closure1.doCall$original(ReportTask.groovy:51)
	at com.github.jk1.license.task.ReportTask$_getClasspath_closure1.doCall(ReportTask.groovy)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at com.github.jk1.license.task.ReportTask.getClasspath(ReportTask.groovy:50)
	at com.github.jk1.license.task.ReportTask_Decorated.getClasspath(Unknown Source)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at org.gradle.internal.reflect.annotations.impl.DefaultPropertyAnnotationMetadata.getPropertyValue(DefaultPropertyAnnotationMetadata.java:97)
	at org.gradle.internal.properties.annotations.DefaultTypeMetadataStore$DefaultPropertyMetadata.getPropertyValue(DefaultTypeMetadataStore.java:284)
	at org.gradle.internal.properties.bean.DefaultPropertyWalker$1.lambda$visitLeaf$0(DefaultPropertyWalker.java:90)
	at org.gradle.internal.deprecation.DeprecationLogger.whileDisabled(DeprecationLogger.java:253)
	at org.gradle.internal.properties.bean.DefaultPropertyWalker$CachedPropertyValue.lambda$new$0(DefaultPropertyWalker.java:107)
	at com.google.common.base.Suppliers$NonSerializableMemoizingSupplier.get(Suppliers.java:181)
	at org.gradle.internal.properties.bean.DefaultPropertyWalker$CachedPropertyValue.call(DefaultPropertyWalker.java:149)
	at org.gradle.util.internal.GUtil.uncheckedCall(GUtil.java:437)
	at org.gradle.util.internal.DeferredUtil.unpackNestableDeferred(DeferredUtil.java:83)
	at org.gradle.util.internal.DeferredUtil.unpack(DeferredUtil.java:57)
	at org.gradle.util.internal.DeferredUtil.unpackOrNull(DeferredUtil.java:49)
	at org.gradle.api.internal.tasks.properties.InputParameterUtils.prepareInputParameterValue(InputParameterUtils.java:38)
	at org.gradle.api.internal.tasks.properties.InputParameterUtils.prepareInputParameterValue(InputParameterUtils.java:30)
	... 69 more
@bric3
Copy link
Author

bric3 commented Jun 20, 2024

Even explicitly configuring the projects in the parent project doesn't help

extensions.configure<LicenseReportExtension> {
    projects = (subprojects - project(":modules")).toTypedArray()
    // projects = arrayOf(
    //     project(":modules:jvm"),
    //     project(":modules:go"),
    //     project(":modules:js"),
    //     project(":modules:php"),
    //     project(":modules:python"),
    //     project(":modules:ruby"),
    // )
}

@Vampire
Copy link
Contributor

Vampire commented Jul 30, 2024

I guess you need to provide an MCVE, because for me it works fine on a multi-module project, so there has to be some edge-case you are hitting.

@Vampire
Copy link
Contributor

Vampire commented Aug 29, 2024

Also in your last screenshot you are looking at the wrong field.
You are looking at project of Task.
You have to look at projects in config which for you is a 1-sized array containing only a null entry.

@bric3
Copy link
Author

bric3 commented Aug 30, 2024

Sorry I put aside this issue for a couple of months, I'll take a fresher look, there have been quite changes since then in the build file.

@bric3
Copy link
Author

bric3 commented Aug 30, 2024

OK I don't know if the message were back then (Gradle 8.8) — I would assume they were — so I feel pretty stupid, the build is failing with these messages now (Gradle 8.10) :

2 problems were found storing the configuration cache.
- Task `:generateLicenseReport` of type `com.github.jk1.license.task.ReportTask`: cannot deserialize object of type 'org.gradle.api.Project' as these are not supported with the configuration cache.
  See https://docs.gradle.org/8.10/userguide/configuration_cache.html#config_cache:requirements:disallowed_types
- Task `:generateLicenseReport` of type `com.github.jk1.license.task.ReportTask`: cannot serialize object of type 'org.gradle.api.internal.project.LifecycleAwareProject', a subtype of 'org.gradle.api.Project', as these are not supported with the configuration cache.
  See https://docs.gradle.org/8.10/userguide/configuration_cache.html#config_cache:requirements:disallowed_types

See the complete report at file:///Users/brice.dutheil/go/src/github.com/DataDog/datadog-intellij-plugin/build/reports/configuration-cache/9npi88kle0xljc5ipkr6p3pr3/5zyu60caq1c85gip0dv3e8wud/configuration-cache-report.html

And indeed I have the gradle configuration cache enabled by default in the gradle properties file:

org.gradle.configuration-cache=true

Turning it off made the task work

 ./gradlew generateLicenseReport -Dorg.gradle.configuration-cache=false

@bric3
Copy link
Author

bric3 commented Aug 30, 2024

@Vampire That said I'm not sure this task can be used from an existing build without disabling the configuration cache. E.g. something like this

tasks {
    register("assemble") {
        dependsOn(generateLicenseReport)
    }
}

extensions.configure<LicenseReportExtension> {
    projects = subprojects.toTypedArray()
}

Note I'm using

  • Gradle 8.10
  • com.github.jk1.dependency-license-report 2.8

I've seen some work started since #255, #269.

@Vampire
Copy link
Contributor

Vampire commented Aug 30, 2024

Yeah, CC will cause that to be null indeed, so I'd say this is a duplicate of CC incompatible issue. You can probably mark the task as not compatible for the moment to not use CC if the task is executed in the same run

@bric3
Copy link
Author

bric3 commented Aug 30, 2024

I don't think notCompatibleWithConfigurationCache("Unsupported") can work entirely (I coudn't) because the build is complaining about the project which is an input to the task especially when the warning mode is enabled in the properties.

org.gradle.configuration-cache.problems=warn
tasks.withType<ReportTask>().configureEach {
    notCompatibleWithConfigurationCache("Unsupported")
}

Seems related to gradle/gradle#20673

@Vampire
Copy link
Contributor

Vampire commented Aug 30, 2024

Ah right, the CC state is always serialized and then deserialized and used, even with that option set, it is just not persisted. So yeah, makes senes that it still fails.

@Dravarix
Copy link

To fix this, the task input would have to be configured to not take in the project object for use during execution time. You could create a new class that could contain the info you need, like configuration, project name, etc. to potentially avoid this. Just went through this exercise in one of our internal plugins for work. Not too bad to do, but does take some effort to get into compliance with the configuration-cache spec.

@Vampire
Copy link
Contributor

Vampire commented Oct 26, 2024

Yes, as I said, this is a duplicate of the CC incompatibility issue. :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants