jdaugherty commented on code in PR #16094:
URL: https://github.com/apache/grails-core/pull/16094#discussion_r3776026528


##########
grails-gradle/plugins/src/main/groovy/org/grails/gradle/plugin/core/GrailsGradlePlugin.groovy:
##########
@@ -1115,6 +1268,150 @@ ${importStatements}
         }
     }
 
+    /**
+     * Wires up the cache the JDK can write for an application, so the next 
start reads what a
+     * training run worked out rather than working it out again.
+     *
+     * <p>Three steps, because the cache is only usable against the layout it 
was trained on: the
+     * archive is extracted, the extracted application is run and asked for 
its pages, and what the
+     * run recorded is left beside it. An application asks for this with
+     * {@code grails.aotCache.enabled}, and says which of its pages matter.</p>
+     */
+    protected void configureAotCache(Project project) {
+        AotCacheExtension extension = ((ExtensionAware) 
project.extensions.getByName('grails'))
+                .extensions.create('aotCache', AotCacheExtension)
+        extension.enabled.convention(false)
+        extension.paths.convention([])
+        extension.jvmArguments.convention(['-Dspring.aot.enabled=true', 
'-Dgrails.env=production'])
+        extension.port.convention(TRAINING_PORT)
+        
extension.startTimeoutSeconds.convention(TRAINING_START_TIMEOUT_SECONDS)
+
+        project.pluginManager.withPlugin(SPRING_BOOT_PLUGIN) {
+            TaskProvider<?> bootJar = project.tasks.named('bootJar')
+            Provider<Directory> application = 
project.layout.buildDirectory.dir('aot-cache/application')
+            Provider<JavaLauncher> launcher = trainingLauncher(project)
+
+            TaskProvider<Exec> extract = 
project.tasks.register('extractAotCacheApplication', Exec) { Exec task ->
+                task.group = BasePlugin.BUILD_GROUP
+                task.description = 'Extracts the application, which is the 
form the cache is read against'
+                task.onlyIf { extension.enabled.get() }
+                task.dependsOn(bootJar)
+                // Named so the extraction is skipped when the archive it came 
from has not moved,
+                // rather than repeated on every run because nothing said what 
it produced.
+                task.inputs.file(project.provider { archiveOf(bootJar) })
+                task.outputs.dir(application)
+                task.doFirst {
+                    File destination = application.get().asFile
+                    project.delete(destination)

Review Comment:
   `project.delete(...)` inside `doFirst` is `Project` access at execution 
time, which is a hard error under the Gradle configuration cache (Gradle 9). 
The surrounding `task.commandLine(...)` also captures `bootJar`/`project` state 
at execution time.
   
   Use `@Inject FileSystemOperations`/`ExecOperations` (or make this a proper 
task type like `TrainAotCacheTask` already is) and resolve the archive through 
a `Provider<RegularFile>` input rather than `archiveOf(bootJar)`, which calls 
`TaskProvider.get()` eagerly.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to