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

ThymeleafAutoConfiguration fails if thymeleaf-spring5 is not present #16079

Closed
4 tasks done
kazuki43zoo opened this issue Mar 4, 2019 · 20 comments
Closed
4 tasks done
Labels
status: first-timers-only An issue that can only be worked on by brand new contributors status: superseded An issue that has been superseded by another type: bug A general bug

Comments

@kazuki43zoo
Copy link
Contributor

kazuki43zoo commented Mar 4, 2019

Hi, this is a first-timers-only issue. This means we've worked to make it more legible to folks who either haven't contributed to our codebase before, or even folks who haven't contributed to open source before.

If that's you, we're interested in helping you take the first step and can answer questions and help you out as you do. Note that we're especially interested in contributions from people from groups underrepresented in free and open source software!

If you have contributed before, consider leaving this one for someone new, and looking through our general ideal-for-contribution issues. Thanks!

Background

Auto-configurations declare conditions to make sure that they back-off when conditions aren't met. For instance, @ConditionalOnClass allows to refer to classes that must be present on the classpath for an auto-configuration to be considered. Spring Boot will parse the bytecode using ASM to identify those classes and skip the auto-configuration altogether if one of them is not present.

Problem

The thymeleaf auto-configuration support relies on the Spring integration module provided by the Thymeleaf project (currently thymeleaf-spring5). Unfortunately, ThymeleafAutoConfiguration only checks for a class in the core thymelaf jar (thymeleaf): if the core jar is present but the integration one isn't, the auto-configuration will be considered and fail:

java.lang.IllegalStateException: Error processing condition on org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration$ThymeleafDefaultConfiguration.templateEngine
	at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:64) ~[spring-boot-autoconfigure-2.1.3.RELEASE.jar:2.1.3.RELEASE]
	at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:108) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod(ConfigurationClassBeanDefinitionReader.java:181) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:141) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:117) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:327) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:232) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:275) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:95) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:705) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:531) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775) [spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) [spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) [spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260) [spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248) [spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
	at com.example.demo.DemoApplicationKt.main(DemoApplication.kt:13) [classes/:na]
Caused by: java.lang.IllegalStateException: @ConditionalOnMissingBean did not specify a bean using type, name or annotation and the attempt to deduce the bean's type failed
	at org.springframework.boot.autoconfigure.condition.OnBeanCondition$BeanSearchSpec.validate(OnBeanCondition.java:451) ~[spring-boot-autoconfigure-2.1.3.RELEASE.jar:2.1.3.RELEASE]
	at org.springframework.boot.autoconfigure.condition.OnBeanCondition$BeanSearchSpec.<init>(OnBeanCondition.java:441) ~[spring-boot-autoconfigure-2.1.3.RELEASE.jar:2.1.3.RELEASE]
	at org.springframework.boot.autoconfigure.condition.OnBeanCondition$BeanSearchSpec.<init>(OnBeanCondition.java:416) ~[spring-boot-autoconfigure-2.1.3.RELEASE.jar:2.1.3.RELEASE]
	at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getMatchOutcome(OnBeanCondition.java:158) ~[spring-boot-autoconfigure-2.1.3.RELEASE.jar:2.1.3.RELEASE]
	at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:47) ~[spring-boot-autoconfigure-2.1.3.RELEASE.jar:2.1.3.RELEASE]
	... 16 common frames omitted
Caused by: org.springframework.boot.autoconfigure.condition.OnBeanCondition$BeanTypeDeductionException: Failed to deduce bean type for org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration$ThymeleafDefaultConfiguration.templateEngine
	at org.springframework.boot.autoconfigure.condition.OnBeanCondition$BeanSearchSpec.addDeducedBeanTypeForBeanMethod(OnBeanCondition.java:496) ~[spring-boot-autoconfigure-2.1.3.RELEASE.jar:2.1.3.RELEASE]
	at org.springframework.boot.autoconfigure.condition.OnBeanCondition$BeanSearchSpec.addDeducedBeanType(OnBeanCondition.java:483) ~[spring-boot-autoconfigure-2.1.3.RELEASE.jar:2.1.3.RELEASE]
	at org.springframework.boot.autoconfigure.condition.OnBeanCondition$BeanSearchSpec.<init>(OnBeanCondition.java:435) ~[spring-boot-autoconfigure-2.1.3.RELEASE.jar:2.1.3.RELEASE]
	... 19 common frames omitted
Caused by: java.lang.ClassNotFoundException: org.thymeleaf.spring5.SpringTemplateEngine
	at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[na:1.8.0_171]
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_171]
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349) ~[na:1.8.0_171]
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_171]
	at java.lang.Class.forName0(Native Method) ~[na:1.8.0_171]
	at java.lang.Class.forName(Class.java:348) ~[na:1.8.0_171]
	at org.springframework.util.ClassUtils.forName(ClassUtils.java:275) ~[spring-core-5.1.5.RELEASE.jar:5.1.5.RELEASE]
	at org.springframework.boot.autoconfigure.condition.OnBeanCondition$BeanSearchSpec.getReturnType(OnBeanCondition.java:505) ~[spring-boot-autoconfigure-2.1.3.RELEASE.jar:2.1.3.RELEASE]
	at org.springframework.boot.autoconfigure.condition.OnBeanCondition$BeanSearchSpec.addDeducedBeanTypeForBeanMethod(OnBeanCondition.java:491) ~[spring-boot-autoconfigure-2.1.3.RELEASE.jar:2.1.3.RELEASE]
	... 21 common frames omitted

Solution

The conditions on ThymeleafAutoConfiguration should be refined so that we don't process it if thymeleaf-spring5 is not on the classpath. A good solution for this is to extend @ConditionalOnClass to also checks for the presence of SpringTemplateEngine.

Steps to Fix

  • Claim this issue with a comment below and ask any clarifying questions you need
  • Set up a repository locally following the Contributing Guidelines
  • Try to fix the issue following the steps above
  • Commit your changes and start a pull request.
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Mar 4, 2019
@snicoll snicoll added type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged labels Mar 4, 2019
@snicoll snicoll added this to the 2.1.x milestone Mar 4, 2019
@snicoll snicoll changed the title ThymeleafAutoConfiguration is failed without thymeleaf-spring5 ThymeleafAutoConfiguration fails if thymeleaf-spring5 is not present Mar 4, 2019
@snicoll snicoll added the status: first-timers-only An issue that can only be worked on by brand new contributors label Mar 4, 2019
@kandebouya
Copy link

I will work there

@snicoll
Copy link
Member

snicoll commented Mar 4, 2019

Great! Thank you. Please let us know if you have any questions.

@ghost
Copy link

ghost commented Mar 4, 2019

oh i am late again :( i will be here next time! :)

@snicoll
Copy link
Member

snicoll commented Mar 8, 2019

@kandebouya checking in to see if there is anything we can do to help. Please let us know.

@snicoll
Copy link
Member

snicoll commented Mar 12, 2019

@kandebouya we haven't heard back from you and are available if you need help. If we don't hear from you by the end of the week, we'll let someone else have a crack at it. Thanks!

@koziolk
Copy link
Contributor

koziolk commented Mar 12, 2019

@snicoll I can work on it if @kandebouya is not available

@snicoll
Copy link
Member

snicoll commented Mar 13, 2019

Thanks @koziolk, you're third. @oguzyildirim is next if we don't hear from @kandebouya

@ghost
Copy link

ghost commented Mar 13, 2019

I will be 4th :)

@ghost
Copy link

ghost commented Mar 13, 2019

@snicoll If this issue is done (was trying to see if I can really do it or not and well luckily, I did), should we still wait for the turn or can we submit the PR?

@snicoll
Copy link
Member

snicoll commented Mar 14, 2019

@dosdebug as you've indicated yourself, you are 4th so pushing the solution without giving a chance to others to try doesn't seem fair. Once the issue is done you can check if it matches your solution.

@snicoll
Copy link
Member

snicoll commented Mar 20, 2019

@kandebouya we haven't heard from you for two weeks so I suggest that @oguzyildirim takes over now. @oguzyildirim, can you please confirm your interest?

@srinaths
Copy link

I'd love to take it up please let me know if my turn's up.

@snicoll
Copy link
Member

snicoll commented Mar 25, 2019

In the interest of getting this fixed this week as we are releasing 2.1.4 Friday, I'd like to move to the third person on the list (and please answer ASAP if you won't be able to work on it this week). @koziolk are you available to work on it this week? Thanks!

@koziolk
Copy link
Contributor

koziolk commented Mar 25, 2019

@snicoll Yes, I'm available. Will start working on this Today.

@Razi007
Copy link

Razi007 commented Mar 26, 2019

Interested to work here.

@snicoll
Copy link
Member

snicoll commented Mar 27, 2019

@koziolk how is it going? Reminder that we're releasing soon and I'd like to get that change in.

@koziolk
Copy link
Contributor

koziolk commented Mar 27, 2019

@snicoll Good. I'm going to submit a pull request Today.

@ghost
Copy link

ghost commented Mar 27, 2019

@snicoll Just to let you know, if @koziolk could not somehow submit PR, I have my changes ready for this task already.

koziolk added a commit to koziolk/spring-boot that referenced this issue Mar 27, 2019
This commit adds an extra check for the presence of thymeleaf-spring5
library on the classpath. Since now ThymeleafAutoConfiguration is
considered only if both thymeleaf-spring5 and thymeleaf jars are present.

spring-projectsgh-16079
@koziolk
Copy link
Contributor

koziolk commented Mar 27, 2019

@snicoll I've implemented a solution based on what @kazuki43zoo suggested in his comment.

@snicoll
Copy link
Member

snicoll commented Mar 28, 2019

Closing in favour of PR #16341

@snicoll snicoll closed this as completed Mar 28, 2019
@snicoll snicoll added the status: superseded An issue that has been superseded by another label Mar 28, 2019
@snicoll snicoll removed this from the 2.1.x milestone Mar 28, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: first-timers-only An issue that can only be worked on by brand new contributors status: superseded An issue that has been superseded by another type: bug A general bug
Projects
None yet
Development

No branches or pull requests

7 participants