codeconsole commented on code in PR #16472:
URL: https://github.com/apache/grails-core/pull/16472#discussion_r4170240201


##########
grails-doc/src/en/guide/gettingStarted/developmentReloading.adoc:
##########
@@ -64,3 +64,35 @@ Hotswap Agent is an open-source tool that provides advanced 
hot swapping capabil
 Enables limited dynamic reloading via standard JVM hot swapping. This feature 
is built into the JVM and does not require additional configuration beyond 
starting the application with debugging enabled.  Supports automatic reloading 
of static content (such as CSS, JavaScript, or HTML templates) without 
restarting the application.  You can modify and reload Java code changes 
without a full restart, but this is limited to non-structural modifications.  
Changes that affect class or method signatures (e.g., adding new methods, 
fields, or constructors; changing method parameters; or modifying class 
hierarchies) are not supported and will require a restart. This limitation 
stems from the JVM's hot swapping constraints.
 
 *Reloading Mechanism:* standard JVM hot swapping
+
+=== Running More Than One Instance of a Checkout
+
+Two Gradle builds of one checkout share its `build/` directory. While an 
application runs from `build/`, another build of the same checkout (a second 
instance on another port, tests run alongside it, an IDE or a tool compiling in 
the same tree) rewrites the classes it runs from, and Spring Boot Developer 
Tools restarts the running application into a half-written build.
+
+Give each instance a build directory of its own instead, by setting 
`layout.buildDirectory` from a Gradle property for every project in the build:
+
+[source,groovy]
+.build.gradle
+----
+allprojects {
+    def instanceBuildDir = providers.gradleProperty('instanceBuildDir')
+    if (instanceBuildDir.present) {
+        layout.buildDirectory = 
layout.projectDirectory.dir(instanceBuildDir.get())
+    }
+}
+----
+
+Then start each instance with a build directory, a port and a Gradle project 
cache of its own:
+
+[source,shell]
+----
+./gradlew bootRun -PinstanceBuildDir=build-parent/build-8081 \
+    --project-cache-dir=build-parent/build-8081/.gradle \
+    --args='--server.port=8081'

Review Comment:
   Both confirmed, and fixed in 938dbb541e with your layout. With the cache 
inside the build directory, `clean` exited 0 and took `buildOutputCleanup` and 
`vcs-1` out of the running build's project cache; with `instances/8081/.gradle` 
beside `instances/8081/build`, it left the cache alone. Against the forge 
`.gitignore` template, `git check-ignore` matches `instances/8081/build/…`, 
`instances/8081/.gradle/…` and a subproject's `sub/instances/8081/build/…`, 
while `build-parent/build-8081/classes/…` shows as untracked. The paragraph 
under the command now says to keep the cache beside the build directory, not 
inside it, and why the two names stay out of version control.
   



##########
grails-doc/src/en/guide/gettingStarted/developmentReloading.adoc:
##########
@@ -64,3 +64,35 @@ Hotswap Agent is an open-source tool that provides advanced 
hot swapping capabil
 Enables limited dynamic reloading via standard JVM hot swapping. This feature 
is built into the JVM and does not require additional configuration beyond 
starting the application with debugging enabled.  Supports automatic reloading 
of static content (such as CSS, JavaScript, or HTML templates) without 
restarting the application.  You can modify and reload Java code changes 
without a full restart, but this is limited to non-structural modifications.  
Changes that affect class or method signatures (e.g., adding new methods, 
fields, or constructors; changing method parameters; or modifying class 
hierarchies) are not supported and will require a restart. This limitation 
stems from the JVM's hot swapping constraints.
 
 *Reloading Mechanism:* standard JVM hot swapping
+
+=== Running More Than One Instance of a Checkout
+
+Two Gradle builds of one checkout share its `build/` directory. While an 
application runs from `build/`, another build of the same checkout (a second 
instance on another port, tests run alongside it, an IDE or a tool compiling in 
the same tree) rewrites the classes it runs from, and Spring Boot Developer 
Tools restarts the running application into a half-written build.
+
+Give each instance a build directory of its own instead, by setting 
`layout.buildDirectory` from a Gradle property for every project in the build:
+
+[source,groovy]
+.build.gradle
+----
+allprojects {
+    def instanceBuildDir = providers.gradleProperty('instanceBuildDir')
+    if (instanceBuildDir.present) {
+        layout.buildDirectory = 
layout.projectDirectory.dir(instanceBuildDir.get())
+    }
+}
+----
+
+Then start each instance with a build directory, a port and a Gradle project 
cache of its own:
+
+[source,shell]
+----
+./gradlew bootRun -PinstanceBuildDir=build-parent/build-8081 \
+    --project-cache-dir=build-parent/build-8081/.gradle \
+    --args='--server.port=8081'
+----
+
+The project cache (the checkout's `.gradle/` directory) does not move with the 
build directory, and two builds running at once contend for it, so 
`--project-cache-dir` gives each build its own.
+
+The Grails Gradle plugin tells the application where its build directory is. 
It passes `grails.project.class.dir` and `grails.project.resource.dir` to 
`bootRun` and the other forked `JavaExec` and `Test` tasks, so development 
reloading compiles a changed class and copies a changed message bundle into 
that instance's build directory, and the application reads its resources from 
there. An `@Integration` test without an `applicationClass` finds the 
application class next to its own compiled classes, wherever the build 
directory is.

Review Comment:
   Fixed in 52ffa6acf3 much as you suggest: the plugin passes the build 
directory relative to the project through `GrailsProjectOutputDirProvider`, and 
`BuildSettings.TARGET_DIR` reads `grails.project.target.dir` joined to 
`BASE_DIR` (an absolute one kept as it is).
   
   One difference, in bdb139d9ad: `project.target.dir` comes first, not as the 
fallback. It was the only property read, and `-Dgrails.project.target.dir` 
given to Gradle reaches the application as `project.target.dir`, since 
`configureForkSettings` passes `grails.*` system properties on without their 
prefix, so reading the plugin's value first would override anyone who set it 
that way.
   
   `BuildSettingsSpec` covers a relative and an absolute property, 
`project.target.dir` alone and over it, neither, and a development start given 
a moved build directory and no `build/`: `.grailspid` lands in that directory, 
no `build/` is created and nothing is logged. An application started with its 
build directory moved and no `build/` now starts without the ERROR, its marker 
in its own build directory.
   



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