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


##########
grails-gradle/plugins/src/main/groovy/org/grails/gradle/plugin/core/GrailsGradlePlugin.groovy:
##########
@@ -1029,6 +1030,13 @@ ${importStatements}
             // Use a CommandLineArgumentProvider so that the absolute project 
directory path
             // is normalized for build cache relocatability 
(PathSensitivity.RELATIVE).
             task.jvmArgumentProviders.add(new 
GrailsAppBaseDirProvider(project.projectDir))
+            // Where development reloading compiles a changed class and copies 
a changed message bundle, and where
+            // the application reads resources from: the build's own 
directories, wherever the build directory is, not
+            // the build/classes/groovy/main and build/resources/main 
BuildSettings falls back to
+            task.jvmArgumentProviders.add(new 
GrailsProjectOutputDirProvider(BuildSettings.PROJECT_CLASSES_DIR,

Review Comment:
   These providers reach `Test` and `JavaExec`, but not the Groovy compiler, 
and the compiler looks for the build's classes too. An `@Integration` spec 
without `applicationClass` gets its application class at compile time: 
`IntegrationTestAstTransformation` calls `MainClassFinder.searchMainClass`, 
which only looks in `<project>/build/classes/main` and 
`<project>/build/classes/groovy/main`. When it finds nothing, the spec gets no 
`@ContextConfiguration`, and its tests run without an application.
   
   I tried this with the `enable-mvc-check` example, moving its build directory 
to `build-parent/build-8070` from an init script:
   
   - With no `build/` in the project, the compiled 
`WebMvcDefaultsFunctionalSpec` has `@Integration` but no 
`@ContextConfiguration`, and all 7 `integrationTest` tests fail with 
`IllegalStateException: No baseUrl set`.
   - With the default layout, the spec gets `@ContextConfiguration(classes = 
Application, loader = GrailsApplicationContextLoader)` and all 7 pass.
   - With the build directory moved again but a `build/` left by another build 
of the same checkout, all 7 pass, because the lookup finds `Application` in 
that other build.
   
   So the two-instance case in the description doesn't show this, but a 
checkout that only ever builds outside `build/` does. This PR doesn't cause it, 
but it's the same gap. Could it be covered here, or in a follow-up issue?
   
   Passing `grails.project.class.dir` to the compiler wouldn't be enough on its 
own. The compiler daemon runs in `~/.gradle/workers`, so `BuildSettings` finds 
no `grails-app` there and ignores the property: `CLASSES_DIR` is null and 
`BUILD_CLASSES_PATH` is `build/classes/main`. Gradle also reuses a forked 
compiler daemon for a later compile whose argument providers pass nothing, and 
that compile then sees the earlier task's values (gradle/gradle#38395). So a 
value given to the compiler has to be passed on every compile, as 
`GrailsAppBaseDirProvider` passes `base.dir`. The integration test compile 
classpath already contains the main classes directory wherever the build puts 
it (`build-parent/build-8070/classes/groovy/main` here), so looking there may 
be simpler than passing a property.
   



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