Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

404.html page causes error when using Thymeleaf with Spring WebFlux [SPR-17407] #21940

Closed
spring-projects-issues opened this issue Oct 18, 2018 · 7 comments
Assignees
Labels
in: web status: invalid

Comments

@spring-projects-issues
Copy link
Collaborator

@spring-projects-issues spring-projects-issues commented Oct 18, 2018

Mahan Hashemizadeh opened SPR-17407 and commented

I upgraded from Spring boot 2.0.5 --> 2.0.6 but the 404.html page (under templates/error/404.html as I am using Thymeleaf) no longer works in my spring webflux application.

I get the following stacktrace:

java.lang.UnsupportedOperationException: null 
at java.util.Collections$UnmodifiableMap.put(Collections.java:1457) 
at org.thymeleaf.spring5.view.reactive.ThymeleafReactiveView.render(ThymeleafReactiveView.java:361) 
at org.springframework.web.reactive.function.server.DefaultRenderingResponseBuilder$DefaultRenderingResponse.lambda$writeToInternal$2(DefaultRenderingResponseBuilder.java:201)
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:118) 
at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onNext(FluxOnAssembly.java:450) 
at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:67) 
at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onNext(FluxOnAssembly.java:450) 
at reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:76)
...

It appears that DefaultServerResponseBuilder creates as unmodifiableMap model which when passed to ThymeleafReactiveView (in render(...)) fails as it attempts a put(...) on the unmodifiable model.

I haven't created an example app to show this issue, but if you need it then let me know.


Affects: 5.0.10

Issue Links:

  • #21967 ThymeleafReactiveView in conjunction with RouterFunction render fails with UnsupportedOperationException ("is duplicated by")
@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Oct 18, 2018

Brian Clozel commented

Hi Mahan Hashemizadeh

Does this happen only in error views or other views as well? What do the template and the model look like? A sample application would be ideal and avoid a lot of back and forth in comments.

Thanks!

 

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Oct 18, 2018

Mahan Hashemizadeh commented

Hi

You can find the sample application here: https://github.com/mahanhz/templateissue

The application contains two mappings in the controller:

http://localhost:8080/

http://localhost:8080/another-page

Both of these work fine and return the correct views.

However if I go to a non-existent URL like http://localhost:8080/not-a-valid-mapping then I get the error described in this issue, but it should in fact display the 404.html view.

If you then downgrade to Spring Boot 2.0.5 and again go to http://localhost:8080/not-a-valid-mapping you will see that it correctly displays the 404.html view.

Hope this helps. Let me know if you need anything else?

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Oct 22, 2018

Brian Clozel commented

Hi Mahan Hashemizadeh,

This is due to a change in Thymeleaf Spring - you can get your sample working by downgrading the Thymeleaf version like:

ext['thymeleaf.version'] = '3.0.9.RELEASE'

In its implementation, Thymeleaf is trying to add new entries to the existing model map - but since its introduction in Spring 5.0, DefaultRenderingResponseBuilder enforces an immutable map and passes that to the View.render method, which contract does not expect an unmodifiable model.

Arjen Poutsma, rstoyanchev, Juergen Hoeller - any opinion on that? Should we improve the existing View.render doc to expect an immutable map? Or should we remove that constraint from our implementation?

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Oct 22, 2018

Arjen Poutsma commented

View.render method which contract does not expect an unmodifiable model.

The documentation of that method says nothing about mutability, so passing a modifiable map is just as unexpected as passing a modifiable one. At most, the behaviour is undefined; not unexpected.

Personally, I think it's rather odd that a View implementation assumes that the passed map is modifiable, especially in the asynchronous world were immutability is desired. So I think that this is a bug in Thymeleaf: it should make a defensive copy of the data if it wants to modify it. Doing that is a good idea anyway, for other reasons (concurrent modifications).

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Oct 22, 2018

Brian Clozel commented

Thanks Arjen Poutsma, I agree. I'll raise an issue with Thymeleaf. In the meantime, this issue has been raised on Twitter as well.

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Oct 22, 2018

Brian Clozel commented

I've created a Thymeleaf Spring issue, but GitHub seems to be having problems right now, so this might show as 404 for now. 

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Oct 22, 2018

Brian Clozel commented

Closing this as invalid as it will be resolved in Thymeleaf.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web status: invalid
Projects
None yet
Development

No branches or pull requests

2 participants