codeconsole opened a new pull request, #16472:
URL: https://github.com/apache/grails-core/pull/16472

   ## Problem
   
   In development a changed source file is compiled again by 
`GrailsApp.recompile`, into `new File(appDir, 
BuildSettings.BUILD_CLASSES_PATH)`. `BUILD_CLASSES_PATH` is the 
`grails.project.class.dir` system property, or else the fixed 
`build/classes/groovy/main`. The Gradle plugin's fork settings pass only 
`grails.project.target.dir`, set to the build directory's *name*, never 
`grails.project.class.dir`.
   
   So an application whose build directory is not `build/` has each change 
compiled where it does not load classes from. A second instance of one checkout 
built with `-PbuildDir=build-parent/build-8070`, so that a build does not 
rewrite the classes the first instance runs from, is the case we hit: the edit 
lands in `build/classes/groovy/main`, the plugin manager is told of the change 
and replaces the artefact's bean (`Overriding bean definition for bean 
'…Controller' with a different definition`), but the class it loads is the one 
already on the instance's classpath. The old code goes on answering, with 
nothing in the log to say so. And the class written into `build/classes` 
restarts any other instance of the checkout that does run from `build/`.
   
   ## Change
   
   Forked JVM tasks get `grails.project.class.dir` from a new 
`GrailsProjectClassesDirProvider`, beside `GrailsAppBaseDirProvider`: the main 
source set's Groovy classes directory, relative to the project directory, since 
`recompile` joins it to the application directory (an absolute path would be 
appended to it). It is read when the task runs, so a build directory changed 
after the plugin is applied is the one passed, and it is `@Internal`, as the 
classes are already the task's classpath.
   
   With the default build directory the value is `build/classes/groovy/main`, 
what `BuildSettings` already chose, so nothing changes there.
   
   ## Tests
   
   `GrailsGradlePluginToolchainSpec` with a new `bootrun-classes-dir` test 
project: `bootRun` passes `build/classes/groovy/main` by default, and 
`build-parent/build-8070/classes/groovy/main` with the build directory moved 
there. Both fail with the provider not added. The other `bootRun` features in 
the spec pass, and `codenarcMain`/`codenarcTest` are clean for the module.
   
   Verified end to end in an application started with 
`-PbuildDir=build-parent/build-<port>`: before, a controller edit compiled into 
`build/classes` and the page kept serving the old code; with the property 
passed, the edit compiled into the instance's own classes, devtools restarted 
it, and the change was served. I have not run the whole `./gradlew build`.
   


-- 
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