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]