casid / jte

Secure and speedy templates for Java and Kotlin.
https://jte.gg
Apache License 2.0
848 stars 63 forks source link

Classpath Issue with Spring Devtools #401

Closed mbechto closed 1 week ago

mbechto commented 2 weeks ago

Hi,

we just upgraded from 3.1.13 to 3.1.14 and got this on deployment:

java.lang.IllegalStateException: Error processing condition on gg.jte.springframework.boot.autoconfigure.JteAutoConfiguration.jteTemplateEngine
    at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:60)
    at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:108)
    at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod(ConfigurationClassBeanDefinitionReader.java:183)
    at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:144)
    at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:120)
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:429)
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:290)
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:349)
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:118)
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:789)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:607)
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:335)
    at com.mercedesbenz.used.distribution.Application.main(Application.java:15)
Caused by: java.lang.IllegalStateException: Failed to introspect Class [gg.jte.springframework.boot.autoconfigure.JteAutoConfiguration] from ClassLoader [jdk.internal.loader.ClassLoaders@5b40de43]
    at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:483)
    at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:360)
    at org.springframework.util.ReflectionUtils.getUniqueDeclaredMethods(ReflectionUtils.java:417)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.lambda(AbstractAutowireCapableBeanFactory.java:750)
    at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(Unknown Source)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryMethod(AbstractAutowireCapableBeanFactory.java:749)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineTargetType(AbstractAutowireCapableBeanFactory.java:682)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.predictBeanType(AbstractAutowireCapableBeanFactory.java:653)
    at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:1687)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:562)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:534)
    at org.springframework.boot.autoconfigure.condition.OnBeanCondition.collectBeanNamesForType(OnBeanCondition.java:247)
    at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getBeanNamesForType(OnBeanCondition.java:240)
    at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getBeanNamesForType(OnBeanCondition.java:230)
    at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getMatchingBeans(OnBeanCondition.java:183)
    at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getMatchOutcome(OnBeanCondition.java:158)
    at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:47)
    ... 15 common frames omitted
Caused by: java.lang.NoClassDefFoundError: org/springframework/boot/devtools/filewatch/FileSystemWatcher
    at java.base/java.lang.Class.getDeclaredMethods0(Native Method)
    at java.base/java.lang.Class.privateGetDeclaredMethods(Unknown Source)
    at java.base/java.lang.Class.getDeclaredMethods(Unknown Source)
    at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:465)
    ... 31 common frames omitted
Caused by: java.lang.ClassNotFoundException: org.springframework.boot.devtools.filewatch.FileSystemWatcher
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(Unknown Source)
    at java.base/jdk.internal.loader.ClassLoaders.loadClass(Unknown Source)
    at java.base/java.lang.ClassLoader.loadClass(Unknown Source)
    ... 35 common frames omitted

Probably it stems from spring-devtools being excluded in our build. It was added as a dependency in #398. I guess this is normal behavior since one doesn't usually want to include devtools in a production build.

NToppingCCS commented 1 week ago

Can confirm that we're also seeing this same behaviour on attempted deployment since upgrading to 3.1.14. Downgrading back to 3.1.13 solves the issue.

However, we are NOT explicitly excluding spring-devtools from our build as the initial report is.

casid commented 1 week ago

Hmm, I wonder if making spring-devtools an optional dependency would help.

@tschuehly do you know what would be the spring recommended way to fix this?

tschuehly commented 1 week ago

Hmm, I wonder if making spring-devtools an optional dependency would help.

@tschuehly do you know what would be the spring recommended way to fix this?

I'm not sure. Maybe @mhalbritter can tell us?

mhalbritter commented 1 week ago

Devtools should not be a required dependency of JTE.

If you need devtools to develop something, you should use optional=true, like documented here.

If you depend on devtools for some functionality, i'd also use optional=true and then do a runtime class check to see if it's there.

I saw #398 included devtools for the FileWatcher - that's not a good idea to include devtools just for the filewatcher. You could either use the java.nio filewatcher or implement your own.

casid commented 1 week ago

Thank you for looking in to it.

Since this causes problems to users in production, I've reverted the changes in #398 and published a new bugfix release.

@tschuehly we can reintroduce #398, once we have a proper solution for it.