Dependencies of task can be determined sometimes when dependent tasks are backed up by singleton class

sometimes encounter the following error, it is not always reproducible in all our user system. but it did happen on some and when it did, it always occurs.

Could not determine the dependencies of task ‘:taskA’.
> ProjectScopeServices has been closed.

TaskBOwner.createInstance(project)
taskA dependsOn TaskBOwner.getInstance().bTask

class TaskBOwner {
static TaskBOwner instance
Task bTask
static TaskBOwner createInstance(final Project project) {
if (instance == null) {
instance = new TaskBOwner(project)
}
return instance
}
static TaskBOwner getInstance() {
if (instance == null) {
throw new IllegalStateException(‘Instance TaskBOwner is not created’)
}
return instance
}
TaskBOwner(final Project project) {
createBTask()
}
Task createBTask() {
bTask = …
}
}

It seems using singleton class for task to be dependsOn in the build is problematic because of the error above sometimes.

Any insight what might be the cause? is it gradle bug or this kind of usage scenario is discouraged.

Thanks

Yikes… please don’t use the singleton pattern… like… never ever. Not in Gradle, not anywhere… just don’t use it… ever… ever!

Please explain what you’re trying to achieve in Gradle and we can help you solve it without singleton pattern.

Not sure if I mentioned… but singleton pattern sucks

the pattern is mainly helpful for the references.

.i.e somewhere in other part of the build can refer to the taskB like:

TaskBOwner.getInstance().taskB

when doing more configuration for other build tasks. also taskB can be named anything we want and no need to change all over the build.

Again, you’re not really stating your requirement, you’re too focused on your solution. Please step back and tell us your actual requirement.

Its possible you can do something like

allprojects {
   tasks.all { Task t ->
      if (t instanceof TaskB) {
         println "Task $t added in project $project" 
      } 
   } 
}
project(':some-project') {
   task taskB(type:TaskB) {...} 
}