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

   A Spring Boot application that renders its views with GSP could not start. 
`bootRun` on the `gsp-spring-boot` example failed at
   
   ```
   java.lang.IllegalArgumentException: Class name 
[org.grails.spring.aop.autoproxy.GroovyAwareInfrastructureAdvisorAutoProxyCreator]
   is not a known auto-proxy creator class
   ```
   
   and behind that were four more failures in a row, each hidden by the one 
before it. The example now starts, renders, decorates and packages, and its 
runtime test is enabled again.
   
   ## Using GSP from a Spring Boot application
   
   Views render from a plain `SpringApplication`, with no Grails application 
class and no Grails plugins:
   
   ```java
   @Configuration
   @ComponentScan
   @EnableAutoConfiguration
   public class Application {
       public static void main(String[] args) {
           SpringApplication.run(Application.class, args);
       }
   }
   ```
   
   The whole of the example's `application.properties` is now the one property 
that says something about GSP:
   
   ```properties
   sitemesh.decorator.default=main
   ```
   
   `spring.main.allow-circular-references` and 
`spring.main.allow-bean-definition-overriding` are no longer needed. Both were 
opted into because of how the GSP beans were wired, not because the application 
wanted either.
   
   Views compiled by the `compileGroovyPages` build task are now rendered from 
their compiled classes, so an application can ship without its templates:
   
   ```groovy
   jar {
       processResources.exclude('**/*.gsp')
   }
   
   compileGroovyPages {
       source = 
project.file("${project.projectDir}/src/main/resources/templates")
       serverpath = '/'   // the path a standalone application looks a view up 
by
   }
   ```
   
   Templates on disk still win where they are there to edit, so `bootRun` 
re-renders a template as it changes.
   
   ## What changed
   
   **Auto-proxy creators.** `CoreGrailsPlugin` registers a Groovy aware 
auto-proxy creator under Spring's `internalAutoProxyCreator` name, and the 
reflection patch that makes Spring recognise it had sat in a 
`GrailsAutoConfiguration` static initializer since 2015. That held while the 
plugin lifecycle only ran through that class; it now runs for every Spring Boot 
application with grails-core on its class path, so an application registered 
the creator without ever loading the class carrying the patch. The patch moved 
to `GroovyAwareAutoProxyCreators` and is applied where the creator is 
registered.
   
   **The Grails plugin lifecycle runs for a Grails application only** — one 
that `GrailsApp` launched, or one with a Grails application class among its 
sources. An application using a Grails library gets that library's 
auto-configuration and nothing else, rather than a `GrailsApplication`, a 
plugin manager and the beans of every plugin found. Documented in the 8.0 
upgrade notes.
   
   **Bean wiring.** Tag libraries are beans of the context, found by the lookup 
once they exist, rather than held inside it — they are autowired with the 
lookup, so a lookup that held them was a cycle. The GSP codec lookup is 
configured after the codecs module, so its `@ConditionalOnMissingBean` guard 
can do its work instead of being overridden. The core beans that read the 
`GrailsApplication` are contributed only where there is one.
   
   **Standalone GSP.** The view registry `compileGroovyPages` writes is read 
into the page locator; `<g:applyLayout>` resolves its layout; the 
`grailsLayout` namespace is registered, so the capture tags the GSP compiler 
emits no longer reach the browser as markup; the JSP tag library resolver is 
optional, so GSP renders without JSP support on the class path.
   
   **The view registry is written whole** rather than merged into what an 
earlier build left behind, which kept naming views since renamed or removed, 
against classes no longer there.
   
   ## Limitations
   
   - **JSP cannot be served from an executable jar.** Jasper compiles a JSP 
from the servlet context, and a jar packages none, so the example offers its 
JSP rendering only where it can serve one — from a war, or run from the 
project. The JSP libraries stay in every artifact: the GSP form uses Spring's 
form tag library, which is a JSP tag library, and renders nothing without them.
   - **Precompiled views need `serverpath`** set to match the template root. 
The default registers each view below `/WEB-INF/grails-app/views/`, which is 
where a Grails application looks and a standalone application never does.
   - Rendering GSP still puts `grails-core` on the class path for the 
`GrailsApplication` the page locator, tag library lookup and JSP tag library 
resolver read. Making GSP need none of it is a larger piece of work than this.
   


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