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

Use task configuration avoidance in gradle initialization #162

Merged
merged 1 commit into from
Apr 9, 2020

Conversation

rjernst
Copy link
Contributor

@rjernst rjernst commented Apr 8, 2020

Gradle task creation can be heavyweight when hundreds or thousands of
instances of tasks exist. This is especially true in large multi project
builds. Forbidden apis currently always creates a task per source set,
as well as the alias forbiddenApis task. Gradle provides a way to
lazily construct the task, and only configure when the task is actually
needed for a given task graph.

This commit switches the construction of the forbidden apis tasks to use
task registration, when it is available (based on gradle version).

closes #145

Gradle task creation can be heavyweight when hundreds or thousands of
instances of tasks exist. This is especially true in large multi project
builds. Forbidden apis currently always creates a task per source set,
as well as the alias `forbiddenApis` task. Gradle provides a way to
lazily construct the task, and only configure when the task is actually
needed for a given task graph.

This commit switches the construction of the forbidden apis tasks to use
task registration, when it is available (based on gradle version).
@uschindler
Copy link
Member

Hi,

looks great. Did you test it already with Elasticsearch to ensure that it works as expected?

@uschindler uschindler merged commit 261ff53 into policeman-tools:master Apr 9, 2020
@uschindler
Copy link
Member

I just merged it, but the "ant test-gradle" failed with Gradle 5.6:

test-gradle:
   [gradle] Initialized native services in: C:\Users\Uwe Schindler\.gradle\native
   [gradle]
   [gradle] Welcome to Gradle 5.6.2!
   [gradle]
   [gradle] Here are the highlights of this release:
   [gradle]  - Incremental Groovy compilation
   [gradle]  - Groovy compile avoidance
   [gradle]  - Test fixtures for Java projects
   [gradle]  - Manage plugin versions via settings script
   [gradle]
   [gradle] For more details see https://docs.gradle.org/5.6.2/release-notes.html
   [gradle]
   [gradle] To honour the JVM settings for this build a new JVM will be forked. Please consider using the daemon: https://docs.gradle.org/5.6.2/userguide/gradle_daemon.html.
   [gradle] Starting process 'Gradle build daemon'. Working directory: C:\Users\Uwe Schindler\.gradle\daemon\5.6.2 Command: C:\Program Files\Java\jdk-12\bin\java.exe --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.invoke=ALL-UNNAMED --add-opens java.prefs/java.util.prefs=ALL-UNNAMED -XX:MaxMetaspaceSize=256m -XX:+HeapDumpOnOutOfMemoryError -Xms256m -Xmx512m -Dfile.encoding=windows-1252 -Duser.country=DE -Duser.language=de -Duser.variant -cp C:\Program Files\Java\gradle-5.6.2\lib\gradle-launcher-5.6.2.jar org.gradle.launcher.daemon.bootstrap.GradleDaemon 5.6.2
   [gradle] Successfully started process 'Gradle build daemon'
   [gradle] An attempt to start the daemon took 10.642 secs.
   [gradle] The client will now receive all logging from the daemon (pid: 11704). The daemon log file: C:\Users\Uwe Schindler\.gradle\daemon\5.6.2\daemon-11704.out.log
   [gradle] Closing daemon's stdin at end of input.
   [gradle] The daemon will no longer process any standard input.
   [gradle] Daemon will be stopped at the end of the build stopping after processing
   [gradle] Using 8 worker leases.
   [gradle] Starting Build
   [gradle] Settings evaluated using settings file 'C:\Users\Uwe Schindler\Projects\lucene\forbidden-apis\forbidden-apis\build\test-gradle\settings.gradle'.
   [gradle] Projects loaded. Root project using build file 'C:\Users\Uwe Schindler\Projects\lucene\forbidden-apis\forbidden-apis\build\test-gradle\build.gradle'.
   [gradle] Included projects: [root project 'test-gradle']
   [gradle]
   [gradle] > Configure project :
   [gradle] Evaluating root project 'test-gradle' using build file 'C:\Users\Uwe Schindler\Projects\lucene\forbidden-apis\forbidden-apis\build\test-gradle\build.gradle'.
   [gradle] Compiling build file 'C:\Users\Uwe Schindler\Projects\lucene\forbidden-apis\forbidden-apis\build\test-gradle\build.gradle' using SubsetScriptTransformer.
   [gradle] Compiling build file 'C:\Users\Uwe Schindler\Projects\lucene\forbidden-apis\forbidden-apis\build\test-gradle\build.gradle' using BuildScriptTransformer.
   [gradle] You are running forbidden-apis in the Gradle Daemon; disabling classloading cache by default to work around resource leak.
   [gradle]
   [gradle] FAILURE: Build failed with an exception.
   [gradle]
   [gradle] * Where:
   [gradle] Build file 'C:\Users\Uwe Schindler\Projects\lucene\forbidden-apis\forbidden-apis\build\test-gradle\build.gradle' line: 39
   [gradle]
   [gradle] * What went wrong:
   [gradle] A problem occurred evaluating root project 'test-gradle'.
   [gradle] > Could not create task ':forbiddenApisMain'.
   [gradle]    > Project#afterEvaluate(Closure) on root project 'test-gradle' cannot be executed in the current context.
   [gradle]
   [gradle] * Try:
   [gradle] Run with --debug option to get more log output. Run with --scan to get full insights.
   [gradle]
   [gradle] * Exception is:
   [gradle] org.gradle.api.GradleScriptException: A problem occurred evaluating root project 'test-gradle'.
   [gradle]     at org.gradle.groovy.scripts.internal.DefaultScriptRunnerFactory$ScriptRunnerImpl.run(DefaultScriptRunnerFactory.java:93)
   [gradle]     at org.gradle.configuration.DefaultScriptPluginFactory$ScriptPluginImpl$2.run(DefaultScriptPluginFactory.java:227)
   [gradle]     at org.gradle.configuration.ProjectScriptTarget.addConfiguration(ProjectScriptTarget.java:77)
   [gradle]     at org.gradle.configuration.DefaultScriptPluginFactory$ScriptPluginImpl.apply(DefaultScriptPluginFactory.java:232)
   [gradle]     at org.gradle.configuration.BuildOperationScriptPlugin$1$1.run(BuildOperationScriptPlugin.java:69)
   [gradle]     at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:402)
   [gradle]     at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:394)
   [gradle]     at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
   [gradle]     at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
   [gradle]     at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
   [gradle]     at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:92)
   [gradle]     at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
   [gradle]     at org.gradle.configuration.BuildOperationScriptPlugin$1.execute(BuildOperationScriptPlugin.java:66)
   [gradle]     at org.gradle.configuration.BuildOperationScriptPlugin$1.execute(BuildOperationScriptPlugin.java:63)
   [gradle]     at org.gradle.configuration.internal.DefaultUserCodeApplicationContext.apply(DefaultUserCodeApplicationContext.java:49)
   [gradle]     at org.gradle.configuration.BuildOperationScriptPlugin.apply(BuildOperationScriptPlugin.java:63)
   [gradle]     at org.gradle.configuration.project.BuildScriptProcessor$1.run(BuildScriptProcessor.java:45)
   [gradle]     at org.gradle.internal.Factories$1.create(Factories.java:26)
   [gradle]     at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.withMutableState(DefaultProjectStateRegistry.java:201)
   [gradle]     at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.withMutableState(DefaultProjectStateRegistry.java:187)
   [gradle]     at org.gradle.configuration.project.BuildScriptProcessor.execute(BuildScriptProcessor.java:42)
   [gradle]     at org.gradle.configuration.project.BuildScriptProcessor.execute(BuildScriptProcessor.java:26)
   [gradle]     at org.gradle.configuration.project.ConfigureActionsProjectEvaluator.evaluate(ConfigureActionsProjectEvaluator.java:35)
   [gradle]     at org.gradle.configuration.project.LifecycleProjectEvaluator$EvaluateProject$1.run(LifecycleProjectEvaluator.java:107)
   [gradle]     at org.gradle.internal.Factories$1.create(Factories.java:26)
   [gradle]     at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:189)
   [gradle]     at org.gradle.internal.work.StopShieldingWorkerLeaseService.withLocks(StopShieldingWorkerLeaseService.java:40)
   [gradle]     at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.withProjectLock(DefaultProjectStateRegistry.java:227)
   [gradle]     at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.withMutableState(DefaultProjectStateRegistry.java:221)
   [gradle]     at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.withMutableState(DefaultProjectStateRegistry.java:187)
   [gradle]     at org.gradle.configuration.project.LifecycleProjectEvaluator$EvaluateProject.run(LifecycleProjectEvaluator.java:96)
   [gradle]     at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:402)
   [gradle]     at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:394)
   [gradle]     at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
   [gradle]     at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
   [gradle]     at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
   [gradle]     at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:92)
   [gradle]     at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
   [gradle]     at org.gradle.configuration.project.LifecycleProjectEvaluator.evaluate(LifecycleProjectEvaluator.java:68)
   [gradle]     at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:693)
   [gradle]     at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:141)
   [gradle]     at org.gradle.execution.TaskPathProjectEvaluator.configure(TaskPathProjectEvaluator.java:36)
   [gradle]     at org.gradle.execution.TaskPathProjectEvaluator.configureHierarchy(TaskPathProjectEvaluator.java:62)
   [gradle]     at org.gradle.configuration.DefaultProjectsPreparer.prepareProjects(DefaultProjectsPreparer.java:55)
   [gradle]     at org.gradle.configuration.BuildOperatingFiringProjectsPreparer$ConfigureBuild.run(BuildOperatingFiringProjectsPreparer.java:52)
   [gradle]     at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:402)
   [gradle]     at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:394)
   [gradle]     at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
   [gradle]     at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
   [gradle]     at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
   [gradle]     at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:92)
   [gradle]     at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
   [gradle]     at org.gradle.configuration.BuildOperatingFiringProjectsPreparer.prepareProjects(BuildOperatingFiringProjectsPreparer.java:40)
   [gradle]     at org.gradle.initialization.DefaultGradleLauncher.prepareProjects(DefaultGradleLauncher.java:198)
   [gradle]     at org.gradle.initialization.DefaultGradleLauncher.doClassicBuildStages(DefaultGradleLauncher.java:138)
   [gradle]     at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:126)
   [gradle]     at org.gradle.initialization.DefaultGradleLauncher.executeTasks(DefaultGradleLauncher.java:106)
   [gradle]     at org.gradle.internal.invocation.GradleBuildController$1.execute(GradleBuildController.java:60)
   [gradle]     at org.gradle.internal.invocation.GradleBuildController$1.execute(GradleBuildController.java:57)
   [gradle]     at org.gradle.internal.invocation.GradleBuildController$3.create(GradleBuildController.java:85)
   [gradle]     at org.gradle.internal.invocation.GradleBuildController$3.create(GradleBuildController.java:78)
   [gradle]     at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:189)
   [gradle]     at org.gradle.internal.work.StopShieldingWorkerLeaseService.withLocks(StopShieldingWorkerLeaseService.java:40)
   [gradle]     at org.gradle.internal.invocation.GradleBuildController.doBuild(GradleBuildController.java:78)
   [gradle]     at org.gradle.internal.invocation.GradleBuildController.run(GradleBuildController.java:57)
   [gradle]     at org.gradle.tooling.internal.provider.ExecuteBuildActionRunner.run(ExecuteBuildActionRunner.java:31)
   [gradle]     at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
   [gradle]     at org.gradle.launcher.exec.BuildOutcomeReportingBuildActionRunner.run(BuildOutcomeReportingBuildActionRunner.java:63)
   [gradle]     at org.gradle.tooling.internal.provider.ValidatingBuildActionRunner.run(ValidatingBuildActionRunner.java:32)
   [gradle]     at org.gradle.launcher.exec.BuildCompletionNotifyingBuildActionRunner.run(BuildCompletionNotifyingBuildActionRunner.java:39)
   [gradle]     at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$3.call(RunAsBuildOperationBuildActionRunner.java:51)
   [gradle]     at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$3.call(RunAsBuildOperationBuildActionRunner.java:45)
   [gradle]     at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:416)
   [gradle]     at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:406)
   [gradle]     at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
   [gradle]     at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
   [gradle]     at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
   [gradle]     at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:102)
   [gradle]     at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36)
   [gradle]     at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner.run(RunAsBuildOperationBuildActionRunner.java:45)
   [gradle]     at org.gradle.launcher.exec.InProcessBuildActionExecuter$1.transform(InProcessBuildActionExecuter.java:50)
   [gradle]     at org.gradle.launcher.exec.InProcessBuildActionExecuter$1.transform(InProcessBuildActionExecuter.java:47)
   [gradle]     at org.gradle.composite.internal.DefaultRootBuildState.run(DefaultRootBuildState.java:78)
   [gradle]     at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:47)
   [gradle]     at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:31)
   [gradle]     at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:42)
   [gradle]     at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:28)
   [gradle]     at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:78)
   [gradle]     at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:52)
   [gradle]     at org.gradle.tooling.internal.provider.SubscribableBuildActionExecuter.execute(SubscribableBuildActionExecuter.java:59)
   [gradle]     at org.gradle.tooling.internal.provider.SubscribableBuildActionExecuter.execute(SubscribableBuildActionExecuter.java:36)
   [gradle]     at org.gradle.tooling.internal.provider.SessionScopeBuildActionExecuter.execute(SessionScopeBuildActionExecuter.java:68)
   [gradle]     at org.gradle.tooling.internal.provider.SessionScopeBuildActionExecuter.execute(SessionScopeBuildActionExecuter.java:38)
   [gradle]     at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:37)
   [gradle]     at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:26)
   [gradle]     at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:43)
   [gradle]     at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:29)
   [gradle]     at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:60)
   [gradle]     at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:32)
   [gradle]     at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:55)
   [gradle]     at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:41)
   [gradle]     at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:48)
   [gradle]     at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:32)
   [gradle]     at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:68)
   [gradle]     at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
   [gradle]     at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
   [gradle]     at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:39)
   [gradle]     at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
   [gradle]     at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:27)
   [gradle]     at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
   [gradle]     at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:35)
   [gradle]     at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
   [gradle]     at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.create(ForwardClientInput.java:78)
   [gradle]     at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.create(ForwardClientInput.java:75)
   [gradle]     at org.gradle.util.Swapper.swap(Swapper.java:38)
   [gradle]     at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:75)
   [gradle]     at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
   [gradle]     at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:50)
   [gradle]     at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
   [gradle]     at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:63)
   [gradle]     at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
   [gradle]     at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
   [gradle]     at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:82)
   [gradle]     at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
   [gradle]     at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
   [gradle]     at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:52)
   [gradle]     at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:297)
   [gradle]     at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
   [gradle]     at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
   [gradle]     at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
   [gradle] Caused by: org.gradle.api.internal.tasks.DefaultTaskContainer$TaskCreationException: Could not create task ':forbiddenApisMain'.
   [gradle]     at org.gradle.api.internal.tasks.DefaultTaskContainer.taskCreationException(DefaultTaskContainer.java:733)
   [gradle]     at org.gradle.api.internal.tasks.DefaultTaskContainer.access$600(DefaultTaskContainer.java:78)
   [gradle]     at org.gradle.api.internal.tasks.DefaultTaskContainer$TaskCreatingProvider.domainObjectCreationException(DefaultTaskContainer.java:725)
   [gradle]     at org.gradle.api.internal.DefaultNamedDomainObjectCollection$AbstractDomainObjectCreatingProvider.tryCreate(DefaultNamedDomainObjectCollection.java:946)
   [gradle]     at org.gradle.api.internal.tasks.DefaultTaskContainer$TaskCreatingProvider.access$1401(DefaultTaskContainer.java:671)
   [gradle]     at org.gradle.api.internal.tasks.DefaultTaskContainer$TaskCreatingProvider$1.run(DefaultTaskContainer.java:698)
   [gradle]     at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:402)
   [gradle]     at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:394)
   [gradle]     at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
   [gradle]     at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
   [gradle]     at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
   [gradle]     at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:92)
   [gradle]     at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
   [gradle]     at org.gradle.api.internal.tasks.DefaultTaskContainer$TaskCreatingProvider.tryCreate(DefaultTaskContainer.java:694)
   [gradle]     at org.gradle.api.internal.DefaultNamedDomainObjectCollection$AbstractDomainObjectCreatingProvider.getOrNull(DefaultNamedDomainObjectCollection.java:927)
   [gradle]     at org.gradle.api.internal.DefaultNamedDomainObjectCollection.findByName(DefaultNamedDomainObjectCollection.java:294)
   [gradle]     at org.gradle.api.internal.tasks.DefaultTaskContainer.findByName(DefaultTaskContainer.java:570)
   [gradle]     at org.gradle.api.internal.tasks.DefaultTaskContainer.findByName(DefaultTaskContainer.java:77)
   [gradle]     at org.gradle.api.internal.DefaultNamedDomainObjectCollection$ContainerElementsDynamicObject.hasProperty(DefaultNamedDomainObjectCollection.java:519)
   [gradle]     at org.gradle.api.internal.DefaultNamedDomainObjectCollection$ContainerElementsDynamicObject.isConfigureMethod(DefaultNamedDomainObjectCollection.java:547)
   [gradle]     at org.gradle.api.internal.DefaultNamedDomainObjectCollection$ContainerElementsDynamicObject.tryInvokeMethod(DefaultNamedDomainObjectCollection.java:540)
   [gradle]     at org.gradle.internal.metaobject.CompositeDynamicObject.tryInvokeMethod(CompositeDynamicObject.java:98)
   [gradle]     at org.gradle.internal.extensibility.MixInClosurePropertiesAsMethodsDynamicObject.tryInvokeMethod(MixInClosurePropertiesAsMethodsDynamicObject.java:33)
   [gradle]     at org.gradle.groovy.scripts.BasicScript$ScriptDynamicObject.tryInvokeMethod(BasicScript.java:134)
   [gradle]     at org.gradle.internal.metaobject.AbstractDynamicObject.invokeMethod(AbstractDynamicObject.java:162)
   [gradle]     at org.gradle.groovy.scripts.BasicScript.invokeMethod(BasicScript.java:83)
   [gradle]     at build_49019tl44dj4inngbiytsskli.run(C:\Users\Uwe Schindler\Projects\lucene\forbidden-apis\forbidden-apis\build\test-gradle\build.gradle:39)
   [gradle]     at org.gradle.groovy.scripts.internal.DefaultScriptRunnerFactory$ScriptRunnerImpl.run(DefaultScriptRunnerFactory.java:91)
   [gradle]     ... 129 more
   [gradle] Caused by: org.gradle.api.internal.AbstractMutationGuard$IllegalMutationException: Project#afterEvaluate(Closure) on root project 'test-gradle' cannot be executed in the current context.
   [gradle]     at org.gradle.api.internal.AbstractMutationGuard.createIllegalStateException(AbstractMutationGuard.java:39)
   [gradle]     at org.gradle.api.internal.AbstractMutationGuard.assertMutationAllowed(AbstractMutationGuard.java:34)
   [gradle]     at org.gradle.api.internal.project.DefaultProject.assertMutatingMethodAllowed(DefaultProject.java:1430)
   [gradle]     at org.gradle.api.internal.project.DefaultProject.afterEvaluate(DefaultProject.java:1005)
   [gradle]     at org.gradle.api.Project$afterEvaluate.call(Unknown Source)
   [gradle]     at plugin-init$_run_closure4$_closure7.doCall(plugin-init.groovy:64)
   [gradle]     at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   [gradle]     at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
   [gradle]     at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
   [gradle]     at org.gradle.util.ClosureBackedAction.execute(ClosureBackedAction.java:71)
   [gradle]     at org.gradle.util.ConfigureUtil.configureTarget(ConfigureUtil.java:154)
   [gradle]     at org.gradle.util.ConfigureUtil.configureSelf(ConfigureUtil.java:130)
   [gradle]     at org.gradle.api.internal.AbstractTask.configure(AbstractTask.java:587)
   [gradle]     at org.gradle.api.internal.AbstractTask.configure(AbstractTask.java:91)
   [gradle]     at org.gradle.util.ConfigureUtil.configure(ConfigureUtil.java:103)
   [gradle]     at org.gradle.util.ConfigureUtil$WrappedConfigureAction.execute(ConfigureUtil.java:166)
   [gradle]     at org.gradl

BUILD FAILED
C:\Users\Uwe Schindler\Projects\lucene\forbidden-apis\forbidden-apis\build.xml:623: exec returned: 1

So something is not working correctly.

@uschindler
Copy link
Member

Maybe the project.afterEvaluate has to be also moved outside?

@uschindler
Copy link
Member

Hrm, i can't fix this. Should I revert the pull request. Sorry it does not work and I mreged it already. Not sure how to handle this

I will let Jenkins also test with latest Gradle, bt at least Gradle 5.6 does not work (the one I have installed locally).

@uschindler
Copy link
Member

I remeber that I tried the same like you did and failed for the same reason. So I gave up. I just have to find my branch where I tried the same.

@uschindler
Copy link
Member

The reason for that problem is that you can't add a project.afterEvaluate, if the task is generated in a delayed way.
The reason why we I did this was: If you configure the task to use a different classesDir as input, which is not sourceSet's output, then you don't need to compile. Because the final classesDirs setting is populated after project evaluation, i added this.

Problem here is: During the lately created task's configuration, Gradle did not yet apply all settings, so the classesDirs property is still the one from the convention. If the build script has changed it, the change is not yet applied.

I digged around: The only workaround is to hardly depend on sourceSet's output. So if task avoidance is enabled, it will always depend on the sourceSet's output, although the task may be configured to looks somewhere else for classes. IMHO this is also the correct thing to do.

I leave the legacy behaviour for older Gradle versions:

    if (TASK_AVOIDANCE_AVAILABLE) {
      // we have to setup the dependcy, as we don't know what the user does afterwards:
      task.dependsOn(sourceSet.output);
    } else {
      // add dependency to compile task after evaluation, if the classesDirs collection has overlaps with our SourceSet:
      project.afterEvaluate{
        def sourceSetDirs = getSourceSetClassesDirs().files;
        if (classesDirs.any{ sourceSetDirs.contains(it) }) {
          task.dependsOn(sourceSet.output);
        }
      }
    }

Maybe as we are on version 3, let's simply remove the coolness. If somebody wants to inspect some other files outside of the sourceset, heshe should create the task from scratch.

The code should look like this - much easier to understand and no magic:

task.dependsOn(sourceSet.output);

Opinions?

uschindler added a commit that referenced this pull request Apr 9, 2020
…) which was way too clever. Just always depend on sourceSet's output unconditionally.
@uschindler
Copy link
Member

I removed the cleverness completely. Much easier to understand.

@uschindler
Copy link
Member

uschindler commented Apr 9, 2020

As a followup, I refactored a bit of the plugin initialization and also made the Gradle test project that caused the issue above a little bit more self-contained. It now also compiles its sources before checking, so its more real-world like.

See this commit: 3242ec4

@rjernst
Copy link
Contributor Author

rjernst commented Apr 9, 2020

Thanks @uschindler! I was in the middle of testing Elasticsearch; I had only created the PR once ant test-gradle passed. Perhaps there is a way test-gradle could invoke the test build.gradle with the minimum gradle supported, as well as the latest?

@rjernst rjernst deleted the task_avoidance branch April 9, 2020 19:04
@uschindler
Copy link
Member

uschindler commented Apr 9, 2020

I tested it with 3.2 (minimum), 4.0 (changes regarding classesDir) and finally with 5.6 (latest on my laptop). Jenkins ran latest 6 release and also failed in same way: https://jenkins.thetaphi.de/job/Forbidden-APIs-testonly-GradleLatest-Linux/38/console

Could you test latest master branch with Elasticsearch? To me it looks fine now, plugin startup code is also looking better now.

The snapshot builds are also on sonatype, but easiest to build with ant from master and once it's installed in local maven repo you can use with Elasticsearch with that special Gradle -DlocalMaven=true parameter to search for artifacts also locally.

My plan is to use gradle wrapper to go the testing with 3 versions (3.2. 4.0 and 4.9) and maybe latest. Which version did you use? Gradle support is unfortunately very fragile.

@rjernst
Copy link
Contributor Author

rjernst commented Apr 9, 2020

Could you test latest master branch with Elasticsearch?

Tested, and it works now. I finally found how to publish to maven local with ant install-maven-artifacts. ./gradlew precommit now passes. I also confirmed this failed with the initial version of my PR before your followups.

Which version did you use?

We are currently on gradle 6.3.

@uschindler
Copy link
Member

Did you see a speed improvement by the task configuration avoidance? I think to see it, you need all plugins support it, right?

@rjernst
Copy link
Contributor Author

rjernst commented Apr 9, 2020

Yes, anything that is explicitly configuring forbidden apis needs to switch to using TaskProviders, which means instead of:

forbiddenApisMain {
  // some configuration
}

one does this:

tasks.named('forbiddenApisMain').configure {
  // some configuration
}

I did this in Elasticsearch along with using a 3.0 snapshot. There are 800+ forbidden apis tasks. On master, it takes about 0.25 seconds to configure those. On my branch it is shaved to 0.06 seconds. So yes, we do see the much of the speed improvement we were hoping for.

rjernst added a commit to rjernst/elasticsearch that referenced this pull request Apr 9, 2020
Currently forbidden apis accounts for 800+ tasks in the build. These
tasks are aggressively created by the plugin. In forbidden apis 3.0, we
will get task avoidance
(policeman-tools/forbidden-apis#162), but we
need to ourselves use the same task avoidance mechanisms to not trigger
these task creations. This commit does that for our foribdden apis
usages, in preparation for upgrading to 3.0 when it is released.
rjernst added a commit to elastic/elasticsearch that referenced this pull request Apr 15, 2020
Currently forbidden apis accounts for 800+ tasks in the build. These
tasks are aggressively created by the plugin. In forbidden apis 3.0, we
will get task avoidance
(policeman-tools/forbidden-apis#162), but we
need to ourselves use the same task avoidance mechanisms to not trigger
these task creations. This commit does that for our foribdden apis
usages, in preparation for upgrading to 3.0 when it is released.
rjernst added a commit to elastic/elasticsearch that referenced this pull request Apr 15, 2020
Currently forbidden apis accounts for 800+ tasks in the build. These
tasks are aggressively created by the plugin. In forbidden apis 3.0, we
will get task avoidance
(policeman-tools/forbidden-apis#162), but we
need to ourselves use the same task avoidance mechanisms to not trigger
these task creations. This commit does that for our foribdden apis
usages, in preparation for upgrading to 3.0 when it is released.
@uschindler uschindler self-assigned this Apr 26, 2020
@uschindler uschindler added this to the 3.0 milestone Apr 26, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

Gradle: use new lazy tasks API when supported (Gradle 4.9+)
2 participants