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

CannotGetJdbcConnectionException in Spring Boot if I use a suspend function in @RestController #21431

Closed
MikeMitterer opened this issue May 13, 2020 · 3 comments
Labels
status: invalid An issue that we don't feel is valid

Comments

@MikeMitterer
Copy link

MikeMitterer commented May 13, 2020

My RestController has this function:

    @GetMapping("/wait")
    suspend fun waitForSeconds(@RequestParam(value = "seconds", defaultValue = "1") seconds: Long): String {
        val now = DateTime.now()
        delay(seconds * 1000)
        val then = DateTime.now()
        return "Diff between: ${then.toDateTimeISO()} and ${now.toDateTimeISO()} is: ${Seconds.secondsBetween(now, then).seconds}sec(s)"
    }

My dependencies are:

implementation("org.springframework.boot:spring-boot-starter-webflux")
...
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlinCoroutines_version")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor:$kotlinCoroutines_version")

[Update]
If I call the "wait"-API-Function
If I start the server
I get

java.lang.TypeNotPresentException: Type org.springframework.jdbc.CannotGetJdbcConnectionException not present
	at java.base/sun.reflect.generics.factory.CoreReflectionFactory.makeNamedType(CoreReflectionFactory.java:117)
	at java.base/sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:125)
	at java.base/sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49)
	at java.base/sun.reflect.generics.visitor.Reifier.reifyTypeArguments(Reifier.java:68)
	at java.base/sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:138)
	at java.base/sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49)
	at java.base/sun.reflect.generics.repository.ClassRepository.computeSuperclass(ClassRepository.java:104)
	at java.base/sun.reflect.generics.repository.ClassRepository.getSuperclass(ClassRepository.java:86)
	at java.base/java.lang.Class.getGenericSuperclass(Class.java:955)
	at org.springframework.core.ResolvableType.getSuperType(ResolvableType.java:467)
	at org.springframework.core.ResolvableType.as(ResolvableType.java:456)
	at org.springframework.core.ResolvableType.forClass(ResolvableType.java:1041)
	at org.springframework.boot.diagnostics.AbstractFailureAnalyzer.getCauseType(AbstractFailureAnalyzer.java:56)
	at org.springframework.boot.diagnostics.AbstractFailureAnalyzer.analyze(AbstractFailureAnalyzer.java:33)
	at org.springframework.boot.diagnostics.FailureAnalyzers.analyze(FailureAnalyzers.java:111)
	at org.springframework.boot.diagnostics.FailureAnalyzers.reportException(FailureAnalyzers.java:104)
	at org.springframework.boot.SpringApplication.reportFailure(SpringApplication.java:816)
	at org.springframework.boot.SpringApplication.handleRunFailure(SpringApplication.java:801)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:325)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215)
	at at.mikemitterer.catshostel.Application$Companion.main(Application.kt:46)
	at at.mikemitterer.catshostel.Application.main(Application.kt)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:567)
	at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: java.lang.ClassNotFoundException: org.springframework.jdbc.CannotGetJdbcConnectionException
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:602)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
	at java.base/java.lang.Class.forName0(Native Method)
	at java.base/java.lang.Class.forName(Class.java:416)
	at java.base/sun.reflect.generics.factory.CoreReflectionFactory.makeNamedType(CoreReflectionFactory.java:114)
	... 27 common frames omitted
2020-05-12 16:03:28.814 [restartedMain] ERROR o.s.boot.SpringApplication - Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerMapping' defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: Unsupported suspending handler method detected: public java.lang.Object at.mikemitterer.catshostel.routes.BasicController.waitForSeconds(long,kotlin.coroutines.Continuation)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1796)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:595)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:895)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141)
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747)
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215)
	at at.mikemitterer.catshostel.Application$Companion.main(Application.kt:46)
	at at.mikemitterer.catshostel.Application.main(Application.kt)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:567)
	at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: java.lang.IllegalStateException: Unsupported suspending handler method detected: public java.lang.Object at.mikemitterer.catshostel.routes.BasicController.waitForSeconds(long,kotlin.coroutines.Continuation)
	at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping$MappingRegistry.register(AbstractHandlerMethodMapping.java:597)
	at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.registerHandlerMethod(AbstractHandlerMethodMapping.java:318)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.registerHandlerMethod(RequestMappingHandlerMapping.java:377)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.registerHandlerMethod(RequestMappingHandlerMapping.java:74)
	at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.lambda$detectHandlerMethods$1(AbstractHandlerMethodMapping.java:288)
	at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:684)
	at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.detectHandlerMethods(AbstractHandlerMethodMapping.java:286)
	at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.processCandidateBean(AbstractHandlerMethodMapping.java:258)
	at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.initHandlerMethods(AbstractHandlerMethodMapping.java:217)
	at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.afterPropertiesSet(AbstractHandlerMethodMapping.java:205)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.afterPropertiesSet(RequestMappingHandlerMapping.java:188)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1855)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1792)
	... 22 common frames omitted
@wilkinsona
Copy link
Member

Thanks for the report. There are two parts to it.

The first is somewhat similar to spring-projects/spring-framework#25050. It's not clear from the output shared above, but I think this is being reported by FailureAnalyzers via debug logging and, while ugly, isn't causing a failure. It seems valid for java.lang.TypeNotPresentException to be thrown by the call to java.lang.Class.getGenericSuperclass from ResolvableType. I've opened spring-projects/spring-framework#25064 to see if Framework can handle the exception.

The second is that the suspending handler method has been identified as one that is unsupported. The stack suggests that you are using Spring MVC rather than Spring WebFlux which contradicts the dependencies you've listed. So that we can be certain of what's happening in your app, can you please provide a minimal sample that reproduces the problem you have described? You can do so by zipping it up and attaching it to this issue or by pushing it to a separate repository on GitHub.

@wilkinsona wilkinsona added the status: waiting-for-feedback We need additional information before we can continue label May 13, 2020
@MikeMitterer
Copy link
Author

Thanks! It's in the sbsuspend-branch: https://github.com/MikeMitterer/kotlin-catshostel-sb/tree/sbsuspend

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels May 13, 2020
@wilkinsona
Copy link
Member

Thanks for the link to the app.

As suspected, the problem is that you are using Spring MVC rather than Spring WebFlux. Unlike WebFlux, MVC does not support suspending handler methods. You are using MVC because of your dependency on spring-boot-starter-websocket which pulls in spring-boot-starter-web.

WebFlux's WebSocket support (part of the spring-webflux module) isn't a drop in replacement for WebSocket support that's part of spring-websocket. If you want to use WebFlux with your app, you'll have to rewrite the WebSocket-related parts of it.

If you have any further questions, please follow up on Stack Overflow or Gitter. As mentioned in the guidelines for contributing, we prefer to use GitHub issues only for bugs and enhancements.

@wilkinsona wilkinsona added status: invalid An issue that we don't feel is valid and removed status: feedback-provided Feedback has been provided status: waiting-for-triage An issue we've not yet triaged labels May 13, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: invalid An issue that we don't feel is valid
Projects
None yet
Development

No branches or pull requests

3 participants