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]