konrad-kaminski / spring-kotlin-coroutine Goto Github PK
View Code? Open in Web Editor NEWKotlin coroutine support for Spring.
Kotlin coroutine support for Spring.
To allow template.findById<User>(id)
instead of template.findById(id, User::class.java)
.
Component | Version |
---|---|
Kotlin | 1.1.60 |
kotlinx.coroutine | 0.19.3 |
Sprint Boot | 2.0.0.M6 |
spring-webmvc-kotlin-coroutine | 0.3.0 |
The moment I add the @EnableCoroutine
annotation to my application, I get the following error at startup.
I guess the relevant part is:
Caused by: java.lang.ClassNotFoundException: reactor.core.scheduler.Scheduler
Here is the full Stack Trace:
2017-11-14 16:43:19.174 ERROR 9204 --- [ restartedMain] o.s.boot.SpringApplication : Application startup failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'coroutineAnnotationBeanPostProcessor' defined in class path resource [org/springframework/kotlin/experimental/coroutine/context/ProxyCoroutineConfiguration.class]: Unsatisfied dependency expressed through method 'coroutineAnnotationBeanPostProcessor' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'globalCoroutineContextResolver' defined in org.springframework.kotlin.experimental.coroutine.context.CoroutineContextResolverConfiguration: Unexpected exception during bean creation; nested exception is java.lang.reflect.InvocationTargetException
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:723) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:458) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1249) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1098) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:502) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:312) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$116/905145750.getObject(Unknown Source) ~[na:na]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:310) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:205) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.registerBeanPostProcessors(PostProcessorRegistrationDelegate.java:226) ~[spring-context-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:709) ~[spring-context-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:534) ~[spring-context-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:122) ~[spring-boot-2.0.0.M6.jar:2.0.0.M6]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:751) [spring-boot-2.0.0.M6.jar:2.0.0.M6]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:387) [spring-boot-2.0.0.M6.jar:2.0.0.M6]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:327) [spring-boot-2.0.0.M6.jar:2.0.0.M6]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1245) [spring-boot-2.0.0.M6.jar:2.0.0.M6]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1233) [spring-boot-2.0.0.M6.jar:2.0.0.M6]
at de.zalando.contentsolutions.ems.ApplicationKt.main(Application.kt:15) [classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_51]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_51]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_51]
at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_51]
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) [spring-boot-devtools-2.0.0.M6.jar:2.0.0.M6]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'globalCoroutineContextResolver' defined in org.springframework.kotlin.experimental.coroutine.context.CoroutineContextResolverConfiguration: Unexpected exception during bean creation; nested exception is java.lang.reflect.InvocationTargetException
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:518) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:312) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$116/905145750.getObject(Unknown Source) ~[na:na]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:310) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:251) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1133) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1060) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:809) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:715) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
... 25 common frames omitted
Caused by: java.lang.reflect.InvocationTargetException: null
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_51]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_51]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_51]
at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_51]
at kotlin.reflect.jvm.internal.impl.load.kotlin.reflect.ReflectClassStructure.processAnnotationArguments(ReflectKotlinClass.kt:173) ~[kotlin-reflect-1.1.60.jar:1.1.60-release-55 (1.1.60)]
at kotlin.reflect.jvm.internal.impl.load.kotlin.reflect.ReflectClassStructure.processAnnotation(ReflectKotlinClass.kt:162) ~[kotlin-reflect-1.1.60.jar:1.1.60-release-55 (1.1.60)]
at kotlin.reflect.jvm.internal.impl.load.kotlin.reflect.ReflectClassStructure.loadMethodAnnotations(ReflectKotlinClass.kt:97) ~[kotlin-reflect-1.1.60.jar:1.1.60-release-55 (1.1.60)]
at kotlin.reflect.jvm.internal.impl.load.kotlin.reflect.ReflectClassStructure.visitMembers(ReflectKotlinClass.kt:87) ~[kotlin-reflect-1.1.60.jar:1.1.60-release-55 (1.1.60)]
at kotlin.reflect.jvm.internal.impl.load.kotlin.reflect.ReflectKotlinClass.visitMembers(ReflectKotlinClass.kt:68) ~[kotlin-reflect-1.1.60.jar:1.1.60-release-55 (1.1.60)]
at kotlin.reflect.jvm.internal.impl.load.kotlin.AbstractBinaryClassAnnotationAndConstantLoader.loadAnnotationsAndInitializers(AbstractBinaryClassAnnotationAndConstantLoader.kt:257) ~[kotlin-reflect-1.1.60.jar:1.1.60-release-55 (1.1.60)]
at kotlin.reflect.jvm.internal.impl.load.kotlin.AbstractBinaryClassAnnotationAndConstantLoader.access$loadAnnotationsAndInitializers(AbstractBinaryClassAnnotationAndConstantLoader.kt:38) ~[kotlin-reflect-1.1.60.jar:1.1.60-release-55 (1.1.60)]
at kotlin.reflect.jvm.internal.impl.load.kotlin.AbstractBinaryClassAnnotationAndConstantLoader$storage$1.invoke(AbstractBinaryClassAnnotationAndConstantLoader.kt:44) ~[kotlin-reflect-1.1.60.jar:1.1.60-release-55 (1.1.60)]
at kotlin.reflect.jvm.internal.impl.load.kotlin.AbstractBinaryClassAnnotationAndConstantLoader$storage$1.invoke(AbstractBinaryClassAnnotationAndConstantLoader.kt:38) ~[kotlin-reflect-1.1.60.jar:1.1.60-release-55 (1.1.60)]
at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$MapBasedMemoizedFunction.invoke(LockBasedStorageManager.java:408) ~[kotlin-reflect-1.1.60.jar:1.1.60-release-55 (1.1.60)]
at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$MapBasedMemoizedFunctionToNotNull.invoke(LockBasedStorageManager.java:483) ~[kotlin-reflect-1.1.60.jar:1.1.60-release-55 (1.1.60)]
at kotlin.reflect.jvm.internal.impl.load.kotlin.AbstractBinaryClassAnnotationAndConstantLoader.findClassAndLoadMemberAnnotations(AbstractBinaryClassAnnotationAndConstantLoader.kt:141) ~[kotlin-reflect-1.1.60.jar:1.1.60-release-55 (1.1.60)]
at kotlin.reflect.jvm.internal.impl.load.kotlin.AbstractBinaryClassAnnotationAndConstantLoader.findClassAndLoadMemberAnnotations$default(AbstractBinaryClassAnnotationAndConstantLoader.kt:135) ~[kotlin-reflect-1.1.60.jar:1.1.60-release-55 (1.1.60)]
at kotlin.reflect.jvm.internal.impl.load.kotlin.AbstractBinaryClassAnnotationAndConstantLoader.loadCallableAnnotations(AbstractBinaryClassAnnotationAndConstantLoader.kt:117) ~[kotlin-reflect-1.1.60.jar:1.1.60-release-55 (1.1.60)]
at kotlin.reflect.jvm.internal.impl.serialization.deserialization.MemberDeserializer$getAnnotations$1.invoke(MemberDeserializer.kt:229) ~[kotlin-reflect-1.1.60.jar:1.1.60-release-55 (1.1.60)]
at kotlin.reflect.jvm.internal.impl.serialization.deserialization.MemberDeserializer$getAnnotations$1.invoke(MemberDeserializer.kt:33) ~[kotlin-reflect-1.1.60.jar:1.1.60-release-55 (1.1.60)]
at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedLazyValue.invoke(LockBasedStorageManager.java:323) ~[kotlin-reflect-1.1.60.jar:1.1.60-release-55 (1.1.60)]
at kotlin.reflect.jvm.internal.impl.storage.LockBasedStorageManager$LockBasedNotNullLazyValue.invoke(LockBasedStorageManager.java:370) ~[kotlin-reflect-1.1.60.jar:1.1.60-release-55 (1.1.60)]
at kotlin.reflect.jvm.internal.impl.storage.StorageKt.getValue(storage.kt:39) ~[kotlin-reflect-1.1.60.jar:1.1.60-release-55 (1.1.60)]
at kotlin.reflect.jvm.internal.impl.serialization.deserialization.descriptors.DeserializedAnnotationsWithPossibleTargets.getAnnotations(DeserializedAnnotations.kt) ~[kotlin-reflect-1.1.60.jar:1.1.60-release-55 (1.1.60)]
at kotlin.reflect.jvm.internal.impl.serialization.deserialization.descriptors.DeserializedAnnotationsWithPossibleTargets.findAnnotation(DeserializedAnnotations.kt:57) ~[kotlin-reflect-1.1.60.jar:1.1.60-release-55 (1.1.60)]
at kotlin.reflect.jvm.internal.impl.descriptors.annotations.Annotations$DefaultImpls.hasAnnotation(Annotations.kt:31) ~[kotlin-reflect-1.1.60.jar:1.1.60-release-55 (1.1.60)]
at kotlin.reflect.jvm.internal.impl.serialization.deserialization.descriptors.DeserializedAnnotationsWithPossibleTargets.hasAnnotation(DeserializedAnnotations.kt:48) ~[kotlin-reflect-1.1.60.jar:1.1.60-release-55 (1.1.60)]
at kotlin.reflect.jvm.internal.impl.descriptors.annotations.AnnotationUtilKt.hasInlineOnlyAnnotation(annotationUtil.kt:81) ~[kotlin-reflect-1.1.60.jar:1.1.60-release-55 (1.1.60)]
at kotlin.reflect.jvm.internal.impl.descriptors.annotations.AnnotationUtilKt.isInlineOnly(annotationUtil.kt:74) ~[kotlin-reflect-1.1.60.jar:1.1.60-release-55 (1.1.60)]
at kotlin.reflect.jvm.internal.impl.descriptors.annotations.AnnotationUtilKt.isInlineOnlyOrReifiable(annotationUtil.kt:67) ~[kotlin-reflect-1.1.60.jar:1.1.60-release-55 (1.1.60)]
at kotlin.reflect.jvm.internal.impl.descriptors.annotations.AnnotationUtilKt.isEffectivelyInlineOnly(annotationUtil.kt:70) ~[kotlin-reflect-1.1.60.jar:1.1.60-release-55 (1.1.60)]
at kotlin.reflect.jvm.internal.UtilKt.isPublicInBytecode(util.kt:157) ~[kotlin-reflect-1.1.60.jar:1.1.60-release-55 (1.1.60)]
at kotlin.reflect.jvm.internal.KFunctionImpl$caller$2.invoke(KFunctionImpl.kt:68) ~[kotlin-reflect-1.1.60.jar:1.1.60-release-55 (1.1.60)]
at kotlin.reflect.jvm.internal.KFunctionImpl$caller$2.invoke(KFunctionImpl.kt:34) ~[kotlin-reflect-1.1.60.jar:1.1.60-release-55 (1.1.60)]
at kotlin.reflect.jvm.internal.ReflectProperties$LazySoftVal.invoke(ReflectProperties.java:93) ~[kotlin-reflect-1.1.60.jar:1.1.60-release-55 (1.1.60)]
at kotlin.reflect.jvm.internal.ReflectProperties$Val.getValue(ReflectProperties.java:32) ~[kotlin-reflect-1.1.60.jar:1.1.60-release-55 (1.1.60)]
at kotlin.reflect.jvm.internal.KFunctionImpl.getCaller(KFunctionImpl.kt) ~[kotlin-reflect-1.1.60.jar:1.1.60-release-55 (1.1.60)]
at kotlin.reflect.jvm.ReflectJvmMapping.getJavaMethod(ReflectJvmMapping.kt:62) ~[kotlin-reflect-1.1.60.jar:1.1.60-release-55 (1.1.60)]
at kotlin.reflect.jvm.ReflectJvmMapping.getKotlinFunction(ReflectJvmMapping.kt:137) ~[kotlin-reflect-1.1.60.jar:1.1.60-release-55 (1.1.60)]
at org.springframework.core.KotlinReflectionParameterNameDiscoverer.getParameterNames(KotlinReflectionParameterNameDiscoverer.java:50) ~[spring-core-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.core.PrioritizedParameterNameDiscoverer.getParameterNames(PrioritizedParameterNameDiscoverer.java:55) ~[spring-core-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:456) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1249) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1098) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:502) ~[spring-beans-5.0.1.RELEASE.jar:5.0.1.RELEASE]
... 35 common frames omitted
Caused by: java.lang.TypeNotPresentException: Type reactor.core.scheduler.Scheduler not present
at sun.reflect.annotation.TypeNotPresentExceptionProxy.generateException(TypeNotPresentExceptionProxy.java:46) ~[na:1.8.0_51]
at sun.reflect.annotation.AnnotationInvocationHandler.invoke(AnnotationInvocationHandler.java:83) ~[na:1.8.0_51]
at com.sun.proxy.$Proxy37.value(Unknown Source) ~[na:na]
... 81 common frames omitted
Caused by: java.lang.ClassNotFoundException: reactor.core.scheduler.Scheduler
at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[na:1.8.0_51]
at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_51]
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) ~[na:1.8.0_51]
at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_51]
at java.lang.Class.forName0(Native Method) ~[na:1.8.0_51]
at java.lang.Class.forName(Class.java:348) ~[na:1.8.0_51]
at sun.reflect.generics.factory.CoreReflectionFactory.makeNamedType(CoreReflectionFactory.java:114) ~[na:1.8.0_51]
at sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:125) ~[na:1.8.0_51]
at sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49) ~[na:1.8.0_51]
at sun.reflect.annotation.AnnotationParser.parseSig(AnnotationParser.java:439) ~[na:1.8.0_51]
at sun.reflect.annotation.AnnotationParser.parseClassValue(AnnotationParser.java:420) ~[na:1.8.0_51]
at sun.reflect.annotation.AnnotationParser.parseMemberValue(AnnotationParser.java:349) ~[na:1.8.0_51]
at sun.reflect.annotation.AnnotationParser.parseAnnotation2(AnnotationParser.java:286) ~[na:1.8.0_51]
at sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:120) ~[na:1.8.0_51]
at sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:72) ~[na:1.8.0_51]
at java.lang.reflect.Executable.declaredAnnotations(Executable.java:602) ~[na:1.8.0_51]
at java.lang.reflect.Executable.declaredAnnotations(Executable.java:600) ~[na:1.8.0_51]
at java.lang.reflect.Executable.getDeclaredAnnotations(Executable.java:591) ~[na:1.8.0_51]
at java.lang.reflect.Method.getDeclaredAnnotations(Method.java:629) ~[na:1.8.0_51]
at java.lang.reflect.AccessibleObject.getAnnotations(AccessibleObject.java:207) ~[na:1.8.0_51]
at org.springframework.core.type.StandardAnnotationMetadata.getAnnotatedMethods(StandardAnnotationMetadata.java:161) ~[spring-core-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.retrieveBeanMethodMetadata(ConfigurationClassParser.java:390) ~[spring-context-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:315) ~[spring-context-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:245) ~[spring-context-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.processImports(ConfigurationClassParser.java:610) ~[spring-context-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:300) ~[spring-context-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:245) ~[spring-context-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:198) ~[spring-context-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:166) ~[spring-context-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:316) ~[spring-context-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:233) ~[spring-context-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:273) ~[spring-context-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:93) ~[spring-context-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:693) ~[spring-context-5.0.1.RELEASE.jar:5.0.1.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:531) ~[spring-context-5.0.1.RELEASE.jar:5.0.1.RELEASE]
... 12 common frames omitted
The ResponseEntityResultHandler does not resolve the return type properly.
Example :
data class TestData(val value: String)
private val repo = mutableListOf<TestData>()
@RequestMapping("/testJson", produces = [MediaType.APPLICATION_JSON_UTF8_VALUE], consumes = [MediaType.APPLICATION_JSON_UTF8_VALUE])
@Controller
class JsonController {
@GetMapping("/suspend/{value}")
@ResponseBody
suspend fun get(@PathVariable value: String) = repo.find { it.value == value }
// FAIL (IllegalStateException on ViewResolutionResultHandler because it is not handled by the ResponseEntityResultHandler)
@PostMapping("/suspend")
suspend fun createSuspend(@RequestBody value: TestData): ResponseEntity<TestData> {
repo.add(value)
delay(100)
return ResponseEntity
.created(URI("/testJson/suspend/${value.value}"))
.body(value)
}
// WORKS
@PostMapping("/mono")
fun create(@RequestBody value: TestData): Mono<ResponseEntity<TestData>> {
repo.add(value)
//delay(100)
return Mono.just(ResponseEntity
.created(URI("/testJson/suspend/${value.value}"))
.body(value))
}
}
I am using spring-boot-starter-quartz
for my scheduling-related needs, and adding spring-kotlin-coroutine
to my projects make all Quartz Job creation fail with the following error:
org.quartz.SchedulerException: Job instantiation failed
at org.springframework.scheduling.quartz.AdaptableJobFactory.newJob(AdaptableJobFactory.java:47) ~[spring-context-support-5.0.8.RELEASE.jar:5.0.8.RELEASE]
at org.quartz.core.JobRunShell.initialize(JobRunShell.java:127) ~[quartz-2.3.0.jar:na]
at org.quartz.core.QuartzSchedulerThread.run(QuartzSchedulerThread.java:392) [quartz-2.3.0.jar:na]
Caused by: java.lang.IllegalArgumentException: Parameter specified as non-null is null: method org.springframework.kotlin.experimental.coroutine.event.CoroutineApplicationEventPublisherAwareBeanPostProcessor.postProcessBeforeInitialization, parameter beanName
at org.springframework.kotlin.experimental.coroutine.event.CoroutineApplicationEventPublisherAwareBeanPostProcessor.postProcessBeforeInitialization(CoroutineApplicationEventPublisherAwareBeanPostProcessor.kt) ~[spring-kotlin-coroutine-0.3.6.jar:na]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:416) ~[spring-beans-5.0.8.RELEASE.jar:5.0.8.RELEASE]
As Job beans are created by Spring+Quartz based on a classname, I do not have the option to name the beans.
Should CoroutineApplicationEventPublisherAwareBeanPostProcessor
accept nullable parameters to fix this, or am I missing something?
Hi - first off, great job on putting together coroutine support for Spring.
I've run into a small problem as I've been exploring the demo.
Specifically, adding a companion object to a Spring Component runs into problems. The problem seems to be with the magic being done in Utils.kt with unwrapCompanionClass. Modifying DemoService by adding the "foo" companion object as I've done below, causes a compile error with the "logger" reference as shown below.
@component
open class DemoService {
companion object foo {
val someStaticCounter = AtomicInteger(0)
}
@Scheduled(cron = "0 0 0 1 1 *")
suspend open fun newYear() {
// logger will now cause a compile error
logger.info("Happy New Year!")
}
...
Just updated my coroutine package to 0.30.1
and now I am getting this exception:
Caused by: java.lang.IllegalAccessError: tried to access field kotlinx.coroutines.experimental.Dispatchers.Default from class org.springframework.kotlin.experimental.coroutine.context.CoroutineContexts
at org.springframework.kotlin.experimental.coroutine.context.CoroutineContexts.defaultDispatcher(CoroutineContexts.kt:29)
at org.springframework.kotlin.experimental.coroutine.context.CoroutineContexts$$EnhancerBySpringCGLIB$$f8f15d29.CGLIB$defaultDispatcher$0(<generated>)
at org.springframework.kotlin.experimental.coroutine.context.CoroutineContexts$$EnhancerBySpringCGLIB$$f8f15d29$$FastClassBySpringCGLIB$$1814e945.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:365)
at org.springframework.kotlin.experimental.coroutine.context.CoroutineContexts$$EnhancerBySpringCGLIB$$f8f15d29.defaultDispatcher(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
... 25 common frames omitted
It might be a breaking change from coroutines itself but bug fixes they have are critical.
So after following the instructions described in README.md
running server logs a warning:
WARN - o.s.c.a.ConfigurationClassPostProcessor Cannot enhance @Configuration bean definition 'org.springframework.kotlin.experimental.coroutine.cache.CoroutineCacheConfiguration' since its singleton instance has been created too early. The typical cause is a non-static @Bean method with a BeanDefinitionRegistryPostProcessor return type: Consider declaring such methods as 'static'.
Why is this happening? What is the recommended way to fix it?
Hi, there.
I successfully got the spring-kotlin-coroutine work on my webflux application.
But when I have a following controller handler method, the "request" parameter of type "ServerRequest" could not be be injected and an error message is show as following.
Anyway I can gain access to the ServerRequest object?
Really appreciated if you have time to help fixing my problem.
Code for my controller class:
@RestController
@Coroutine(COMMON_POOL)
open class LoginController {
@PostMapping(path = ["/login"], consumes = [MediaType.APPLICATION_JSON_UTF8_VALUE], produces = [MediaType.APPLICATION_JSON_UTF8_VALUE])
open suspend fun login(@RequestBody param: JSONObject, request: ServerRequest): OperationResult {
// do some login stuff
}
}
And this is the corresponding error message:
java.lang.IllegalStateException: No suitable resolver for argument 0 of type 'org.springframework.web.reactive.function.server.ServerRequest' on public com.lazymonkey.game.pjsh.loginserver.model.OperationResult com.lazymonkey.game.pjsh.loginserver.exception.ExceptionHandlingController.handleException(org.springframework.web.reactive.function.server.ServerRequest,java.lang.Exception)
at org.springframework.web.reactive.result.method.InvocableHandlerMethod.getArgumentError(InvocableHandlerMethod.java:228) ~[spring-webflux-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.reactive.result.method.InvocableHandlerMethod.lambda$findResolver$7(InvocableHandlerMethod.java:207) ~[spring-webflux-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at java.util.Optional.orElseThrow(Optional.java:290) ~[na:1.8.0_162]
at org.springframework.web.reactive.result.method.InvocableHandlerMethod.findResolver(InvocableHandlerMethod.java:207) ~[spring-webflux-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.reactive.result.method.InvocableHandlerMethod.lambda$null$1(InvocableHandlerMethod.java:178) ~[spring-webflux-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at java.util.Optional.orElseGet(Optional.java:267) ~[na:1.8.0_162]
at org.springframework.web.reactive.result.method.InvocableHandlerMethod.lambda$resolveArguments$2(InvocableHandlerMethod.java:177) ~[spring-webflux-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) ~[na:1.8.0_162]
at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948) ~[na:1.8.0_162]
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) ~[na:1.8.0_162]
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) ~[na:1.8.0_162]
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) ~[na:1.8.0_162]
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:1.8.0_162]
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) ~[na:1.8.0_162]
at org.springframework.web.reactive.result.method.InvocableHandlerMethod.resolveArguments(InvocableHandlerMethod.java:183) ~[spring-webflux-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.reactive.result.method.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:136) ~[spring-webflux-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerAdapter.handleException(RequestMappingHandlerAdapter.java:218) ~[spring-webflux-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerAdapter.lambda$handle$0(RequestMappingHandlerAdapter.java:194) ~[spring-webflux-5.0.7.RELEASE.jar:5.0.7.RELEASE]
at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:88) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onError(FluxPeekFuseable.java:222) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onError(FluxPeekFuseable.java:222) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.Operators$MonoSubscriber.onError(Operators.java:1126) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.MonoIgnoreThen$ThenAcceptInner.onError(MonoIgnoreThen.java:305) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onError(FluxMapFuseable.java:128) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.Operators.error(Operators.java:178) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.FluxFlatMap.trySubscribeScalarMap(FluxFlatMap.java:129) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.MonoFlatMap.subscribe(MonoFlatMap.java:53) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.MonoMapFuseable.subscribe(MonoMapFuseable.java:59) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:53) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.drain(MonoIgnoreThen.java:153) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:56) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.MonoPeekFuseable.subscribe(MonoPeekFuseable.java:74) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.MonoPeekFuseable.subscribe(MonoPeekFuseable.java:74) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.MonoOnErrorResume.subscribe(MonoOnErrorResume.java:44) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:150) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:67) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:76) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.innerNext(FluxConcatMap.java:271) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.FluxConcatMap$ConcatMapInner.onNext(FluxConcatMap.java:803) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:115) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:1640) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:156) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:1454) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onSubscribe(Operators.java:1328) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onSubscribe(FluxMapFuseable.java:90) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:54) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.MonoMapFuseable.subscribe(MonoMapFuseable.java:59) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.Mono.subscribe(Mono.java:3080) [reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.drain(FluxConcatMap.java:418) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.onSubscribe(FluxConcatMap.java:210) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:140) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:64) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.FluxConcatMap.subscribe(FluxConcatMap.java:121) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.MonoNext.subscribe(MonoNext.java:40) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.MonoSwitchIfEmpty.subscribe(MonoSwitchIfEmpty.java:44) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.MonoFlatMap.subscribe(MonoFlatMap.java:60) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.MonoFlatMap.subscribe(MonoFlatMap.java:60) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.MonoOnErrorResume.subscribe(MonoOnErrorResume.java:44) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.MonoOnErrorResume.subscribe(MonoOnErrorResume.java:44) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.MonoOnErrorResume.subscribe(MonoOnErrorResume.java:44) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.Mono.subscribe(Mono.java:3080) [reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.drain(MonoIgnoreThen.java:172) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:56) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.MonoPeekFuseable.subscribe(MonoPeekFuseable.java:70) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.core.publisher.MonoPeekTerminal.subscribe(MonoPeekTerminal.java:61) ~[reactor-core-3.1.8.RELEASE.jar:3.1.8.RELEASE]
at reactor.ipc.netty.channel.ChannelOperations.applyHandler(ChannelOperations.java:380) ~[reactor-netty-0.7.8.RELEASE.jar:0.7.8.RELEASE]
at reactor.ipc.netty.http.server.HttpServerOperations.onHandlerStart(HttpServerOperations.java:398) ~[reactor-netty-0.7.8.RELEASE.jar:0.7.8.RELEASE]
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute$$$capture(AbstractEventExecutor.java:163) ~[netty-common-4.1.25.Final.jar:4.1.25.Final]
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java) ~[netty-common-4.1.25.Final.jar:4.1.25.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404) ~[netty-common-4.1.25.Final.jar:4.1.25.Final]
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:465) ~[netty-transport-4.1.25.Final.jar:4.1.25.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884) ~[netty-common-4.1.25.Final.jar:4.1.25.Final]
at java.lang.Thread.run(Thread.java:748) ~[na:1.8.0_162]
When I have an interface
interface Foo {
suspend fun bar(): Any
}
and I have a bean
@Component
@Coroutine(COMMON_POOL)
class FooImpl : Foo {
override suspend fun bar() = Any()
}
injecting FooImpl
causes
***************************
APPLICATION FAILED TO START
***************************
Description:
The bean 'fooImpl' could not be injected as a 'de.rakhman.mipa.controller.FooImpl' because it is a JDK dynamic proxy that implements:
de.rakhman.mipa.controller.Foo
Action:
Consider injecting the bean as one of its interfaces or forcing the use of CGLib-based proxies by setting proxyTargetClass=true on @EnableAsync and/or @EnableCaching.
When creating a bean with @Scope("request")
, it won't work anymore within an asynchronous context. It would be nice if this would be supported from this library.
When using @Cacheable
, the condition must be updated to index into array instead of argument directly, e.g. if argument name is to
the condition must refer to to[0]
. Would it be possible to update the library so it does not mess with @Cacheable
condition?
How can I access/configure SecurityContext inside suspend function?
In this example, UserService::changePassword method access to SecurityContextHolder.getContext(): it is null when controller method has the suspend modifier (changePasswordNotWorking) while default method is working (changePassword). I suppose it is also applicable when service has security annotations:
@RestController
@Coroutine(COMMON_POOL)
class UserController(
val userService: UserService
) {
@PostMapping(
"/api/change-password-working",
consumes = [MediaType.APPLICATION_JSON_UTF8_VALUE],
produces = [MediaType.APPLICATION_JSON_UTF8_VALUE]
)
fun changePassword(@RequestBody body: MutableMap<String, Any?>): SomeObject = userService.changePassword(body)
@PostMapping(
"/api/change-password-not-working",
consumes = [MediaType.APPLICATION_JSON_UTF8_VALUE],
produces = [MediaType.APPLICATION_JSON_UTF8_VALUE]
)
suspend fun changePasswordNotWorking(@RequestBody body: MutableMap<String, Any?>): SomeObject = userService.changePassword(body)
}
I'm trying to use spring-kotlin-coroutine in an existing application, but after rewriting some code to use suspending functions and trying to start the application I get this error message:
2017-12-09 22:40:04.384 ERROR [ main] o.s.b.SpringApplication : Application startup failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'coroutineAnnotationBeanPostProcessor' defined in class path resource [org/springframework/kotlin/experimental/coroutine/context/ProxyCoroutineConfiguration.class]: Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: org.springframework.aop.support.annotation.AnnotationMatchingPointcut.<init>(Ljava/lang/Class;Ljava/lang/Class;Z)V
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.context.support.PostProcessorRegistrationDelegate.registerBeanPostProcessors(PostProcessorRegistrationDelegate.java:225)
at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:703)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:528)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107)
at com.bol.spex.SpexApplicationKt.main(SpexApplication.kt:12)
Caused by: java.lang.NoSuchMethodError: org.springframework.aop.support.annotation.AnnotationMatchingPointcut.<init>(Ljava/lang/Class;Ljava/lang/Class;Z)V
at org.springframework.kotlin.experimental.coroutine.context.CoroutinePointcutAdvisor.<init>(CoroutinePointcutAdvisor.kt:37)
at org.springframework.kotlin.experimental.coroutine.context.CoroutineAnnotationBeanPostProcessor.afterPropertiesSet(CoroutineAnnotationBeanPostProcessor.kt:27)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624)
... 16 more
Hi!
When I add "@EnableCoroutine" to my Application class, build fails with exception:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'DefaultDispatcher' defined in org.springframework.kotlin.experimental.coroutine.context.CoroutineContexts: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [kotlinx.coroutines.experimental.CoroutineDispatcher]: Factory method 'defaultDispatcher' threw exception; nested exception is java.lang.NoClassDefFoundError: kotlinx/coroutines/experimental/Dispatchers at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:590) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1256) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1105) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:503) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:760) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE] at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:869) ~[spring-context-5.0.7.RELEASE.jar:5.0.7.RELEASE] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550) ~[spring-context-5.0.7.RELEASE.jar:5.0.7.RELEASE] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140) ~[spring-boot-2.0.3.RELEASE.jar:2.0.3.RELEASE] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759) [spring-boot-2.0.3.RELEASE.jar:2.0.3.RELEASE] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:395) [spring-boot-2.0.3.RELEASE.jar:2.0.3.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:327) [spring-boot-2.0.3.RELEASE.jar:2.0.3.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1255) [spring-boot-2.0.3.RELEASE.jar:2.0.3.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1243) [spring-boot-2.0.3.RELEASE.jar:2.0.3.RELEASE] at com.mydictionary.ApplicationKt.main(Application.kt:22) [classes/:na] Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [kotlinx.coroutines.experimental.CoroutineDispatcher]: Factory method 'defaultDispatcher' threw exception; nested exception is java.lang.NoClassDefFoundError: kotlinx/coroutines/experimental/Dispatchers at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE] at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:582) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE] ... 18 common frames omitted Caused by: java.lang.NoClassDefFoundError: kotlinx/coroutines/experimental/Dispatchers at org.springframework.kotlin.experimental.coroutine.context.CoroutineContexts.defaultDispatcher(CoroutineContexts.kt:29) ~[spring-kotlin-coroutine-0.3.6.jar:na] at org.springframework.kotlin.experimental.coroutine.context.CoroutineContexts$$EnhancerBySpringCGLIB$$8b78d0d0.CGLIB$defaultDispatcher$1(<generated>) ~[spring-kotlin-coroutine-0.3.6.jar:na] at org.springframework.kotlin.experimental.coroutine.context.CoroutineContexts$$EnhancerBySpringCGLIB$$8b78d0d0$$FastClassBySpringCGLIB$$cba81175.invoke(<generated>) ~[spring-kotlin-coroutine-0.3.6.jar:na] at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) ~[spring-core-5.0.7.RELEASE.jar:5.0.7.RELEASE] at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:361) ~[spring-context-5.0.7.RELEASE.jar:5.0.7.RELEASE] at org.springframework.kotlin.experimental.coroutine.context.CoroutineContexts$$EnhancerBySpringCGLIB$$8b78d0d0.defaultDispatcher(<generated>) ~[spring-kotlin-coroutine-0.3.6.jar:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_181] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_181] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_181] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_181] at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE] ... 19 common frames omitted Caused by: java.lang.ClassNotFoundException: kotlinx.coroutines.experimental.Dispatchers at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[na:1.8.0_181] at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_181] at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349) ~[na:1.8.0_181] at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_181] ... 30 common frames omitted
What's wrong with my configuration?
buildscript {
ext {
kotlinVersion = '1.2.70'
springBootVersion = '2.0.3.RELEASE'
}
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}")
classpath("org.jetbrains.kotlin:kotlin-allopen:${kotlinVersion}")
}
}
apply plugin: 'kotlin'
apply plugin: 'kotlin-spring'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
bootJar {
baseName = 'demo'
version = '0.0.1-SNAPSHOT'
}
repositories {
maven { url 'https://dl.bintray.com/konrad-kaminski/maven' }
mavenCentral()
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
compileKotlin {
kotlinOptions {
freeCompilerArgs = ["-Xjsr305=strict"]
jvmTarget = "1.8"
}
}
compileTestKotlin {
kotlinOptions {
freeCompilerArgs = ["-Xjsr305=strict"]
jvmTarget = "1.8"
}
}
kotlin {
experimental {
coroutines 'enable'
}
}
dependencies {
implementation "org.springframework.boot:spring-boot-starter-web"
implementation 'com.fasterxml.jackson.module:jackson-module-kotlin'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
implementation "org.jetbrains.kotlin:kotlin-reflect"
implementation "com.google.firebase:firebase-admin:6.4.0"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:0.21"
implementation "org.springframework.kotlin:spring-kotlin-coroutine:0.3.6"
implementation "org.springframework.kotlin:spring-webmvc-kotlin-coroutine:0.3.6"
testimplementation 'org.springframework.boot:spring-boot-starter-test'
testimplementation group: 'junit', name: 'junit', version: '4.12'
}
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
task wrapper(type: Wrapper) {
gradleVersion = '2.2.1'
}
task stage(dependsOn: ['build', 'clean'])
build.mustRunAfter clean
I think it would be more relevant to use suspendable List<T>
instead of ReceiveChannel<T>
in methods others than tail()
(where ReceiveChannel
is a perfect fit). The would make CoroutineMongoOperations
even more closer to a suspendable version of MongoOperations
which is a good thing IMO.
According to this blog post, Bintray was sunset starting May 1st and it is now no longer possible to download spring-kotlin-coroutine using the instructions in the README. The download link now returns a 403 error, and none of the files are accessible. Is there an alternative hosting solution currently available? Or maybe publishing to Maven Central as requested in #42 would be a feasible approach?
Opentracing use ThreadLocal to save the tracing scope, how to share it between coroutines using this lib? Any suggestion?
I have updated a little bit my deepdive example in order to use kotlinx.coroutines 0.20 and the map
extension, and it seems this combination breaks the view name resolution. Run https://github.com/sdeleuze/spring-kotlin-deepdive/tree/coroutine-view-issue and go to http://localhost:8080/
to reproduce.
I see the project has a java method named CoroutineUtils.runCoroutine
,so in my opinion,i can run a coroutine in java.But i tried and it failed without invoking the continuation callback.Here is my code:
CoroutineUtils
.runCoroutine(context,
(scope, continuation) -> personMapperB.getName(name),
new Continuation<String>() {
@NotNull
@Override
public CoroutineContext getContext() {
return context;
}
@Override
public void resumeWith(@NotNull Object o) {
System.err.println(123445555);
}
});
So is it possible to invoke in java,if possible how can i do that?Thank you!!!
I having this exception, when I'm trying to use simple RestController
@RestController
@RequestMapping("/coroutine")
open class CoroutineController(
private val myRepository: MyRepository
) : ILogging by LoggingImp<CoroutineController>() {
@GetMapping(value = ["testSuspend"], produces = [MediaType.APPLICATION_JSON_UTF8_VALUE])
open suspend fun testSuspend(): String {
log.debug("testSuspend")
return myRepository.getAllCustomers()
}
}
@Component
@Coroutine(COMMON_POOL)
open class MyRepository {
open suspend fun getAllCustomers(): String {
delay(500)
return "123"
}
}
@SpringBootApplication
@EnableCoroutine
@ComponentScan(basePackages = "com.packageWithControllers")
public class ApiApplication {
public static void main(String[] args) {
SpringApplication.run(ApiApplication.class, args);
}
}
2018-04-17 18:04:39.119 [http-nio-8080-exec-1] DEBUG c.i.b.r.c.json.CoroutineController:23 - testSuspend
2018-04-17 18:04:39.131 [http-nio-8080-exec-1] WARN c.i.b.r.h.e.ExceptionHandlerAdvice:25 - Empty message, see log file
kotlin.KotlinNullPointerException: null
at kotlin.coroutines.experimental.jvm.internal.CoroutineImpl.getFacade(CoroutineImpl.kt:48)
at kotlin.coroutines.experimental.jvm.internal.CoroutineIntrinsics.normalizeContinuation(CoroutineIntrinsics.kt:29)
at kotlinx.coroutines.experimental.BuildersKt.withContext(Builders.kt:109)
at org.springframework.kotlin.experimental.coroutine.util.CoroutineUtils.runCoroutine(CoroutineUtils.java:30)
at org.springframework.kotlin.experimental.coroutine.context.CoroutineMethodInterceptor.invoke(CoroutineMethodInterceptor.kt:48)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689)
at c.i.b.r.c.j.MyRepository$$EnhancerBySpringCGLIB$$728de01c.getAllCustomers(<generated>)
at c.i.b.r.c.j.CoroutineController.testSuspend$suspendImpl(CoroutineController.kt:24)
at c.i.b.r.c.j.CoroutineController.testSuspend(CoroutineController.kt)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:870)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:776)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:978)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:870)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:855)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:119)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at com.incafe.backend.rest.filter.SecurityFilter.doFilterInternal(SecurityFilter.kt:43)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:496)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
<version>1.2.31</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-reflect</artifactId>
<version>1.2.31</version>
</dependency>
<dependency>
<groupId>org.springframework.kotlin</groupId>
<artifactId>spring-kotlin-coroutine</artifactId>
<version>0.3.4</version>
</dependency>
...
</dependencies>
`
Currently the project is published to https://dl.bintray.com/konrad-kaminski/maven. Can this library be published to Maven Central?
DefaultCoroutineWebClient
seems not supporting baseUrl
definition at WebClient
level. For example, see https://github.com/sdeleuze/spring-kotlin-deepdive/blob/step3-coroutine/src/test/kotlin/io/spring/deepdive/HtmlTests.kt which fails if you define DefaultCoroutineWebClient(WebClient.create("http://localhost:$port"))
and just use relative url like client.get().uri("/api/user/")
.
Adding a @Validated
annotation to a coroutine controller (neither for WebMVC nor Webflux).
I'm not sure if this is necessarily an issue with spring-kotlin-coroutine
though, or with Spring's bean validation framework.
Partial stacktrace for WebMVC (created simply by adding @Validated
to the test CoroutineController
):
java.lang.ArrayIndexOutOfBoundsException: 2
at java.util.Arrays$ArrayList.get(Arrays.java:3841) ~[na:1.8.0_181]
at org.hibernate.validator.internal.metadata.aggregated.ParameterMetaData$Builder.build(ParameterMetaData.java:169) ~[hibernate-validator-6.0.12.Final.jar:6.0.12.Final]
at org.hibernate.validator.internal.metadata.aggregated.ExecutableMetaData$Builder.findParameterMetaData(ExecutableMetaData.java:435) ~[hibernate-validator-6.0.12.Final.jar:6.0.12.Final]
at org.hibernate.validator.internal.metadata.aggregated.ExecutableMetaData$Builder.build(ExecutableMetaData.java:388) ~[hibernate-validator-6.0.12.Final.jar:6.0.12.Final]
at org.hibernate.validator.internal.metadata.aggregated.BeanMetaDataImpl$BuilderDelegate.build(BeanMetaDataImpl.java:788) ~[hibernate-validator-6.0.12.Final.jar:6.0.12.Final]
at org.hibernate.validator.internal.metadata.aggregated.BeanMetaDataImpl$BeanMetaDataBuilder.build(BeanMetaDataImpl.java:648) ~[hibernate-validator-6.0.12.Final.jar:6.0.12.Final]
at org.hibernate.validator.internal.metadata.BeanMetaDataManager.createBeanMetaData(BeanMetaDataManager.java:192) ~[hibernate-validator-6.0.12.Final.jar:6.0.12.Final]
at org.hibernate.validator.internal.metadata.BeanMetaDataManager.lambda$getBeanMetaData$0(BeanMetaDataManager.java:160) ~[hibernate-validator-6.0.12.Final.jar:6.0.12.Final]
at java.util.concurrent.ConcurrentMap.computeIfAbsent(ConcurrentMap.java:324) ~[na:1.8.0_181]
at org.hibernate.validator.internal.metadata.BeanMetaDataManager.getBeanMetaData(BeanMetaDataManager.java:159) ~[hibernate-validator-6.0.12.Final.jar:6.0.12.Final]
at org.hibernate.validator.internal.engine.ValidationContext$ValidationContextBuilder.forValidateParameters(ValidationContext.java:619) ~[hibernate-validator-6.0.12.Final.jar:6.0.12.Final]
at org.hibernate.validator.internal.engine.ValidatorImpl.validateParameters(ValidatorImpl.java:254) ~[hibernate-validator-6.0.12.Final.jar:6.0.12.Final]
at org.hibernate.validator.internal.engine.ValidatorImpl.validateParameters(ValidatorImpl.java:224) ~[hibernate-validator-6.0.12.Final.jar:6.0.12.Final]
at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:97) ~[spring-context-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688) ~[spring-aop-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.kotlin.experimental.coroutine.web.CoroutineController$$EnhancerBySpringCGLIB$$220f8cfd.delayedMultiply(<generated>) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_181]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_181]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_181]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_181]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209) ~[spring-web-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) ~[spring-web-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) ~[spring-webmvc-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:891) ~[spring-webmvc-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) ~[spring-webmvc-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991) ~[spring-webmvc-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925) ~[spring-webmvc-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974) ~[spring-webmvc-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:866) ~[spring-webmvc-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:635) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851) ~[spring-webmvc-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-8.5.34.jar:8.5.34]
In CoroutineServerResponse
:
from(other: CoroutineServerResponse)
fun status(status: Int)
fun accepted()
fun noContent()
fun temporaryRedirect(location: URI)
fun badRequest()
fun notFound()
unprocessableEntity()
CoroutineHeadersBuilder
like header(...)
Hey Konrad, since Spring Framework 5.0 has been recently released and now provides official Kotlin support (and not only for WebFlux level, see the reference documentation), do you have any plan to upgrade spring-kotlin-coroutine
to support it (I guess Spring Framework 4.x users could continue to use spring-kotlin-coroutine
0.2.x) ?
Are you planning on publishing the artifacts?
Using suspend function on rest controller ResponseBodyAdvice is not invoked
@Scheduled(fixedDelayString = "\${propertyName}")
suspend fun methodName() = coroutineScope {
}
propertyName is not resolved and Exception is thrown
Caused by: java.lang.IllegalArgumentException: Invalid fixedDelayString value "${propertyName}" - cannot parse into integer
at org.springframework.kotlin.coroutine.scheduler.DefaultSchedulingPolicyProvider.getValue(SchedulingPolicyProvider.kt:70)
at org.springframework.kotlin.coroutine.scheduler.DefaultSchedulingPolicyProvider.getValue$default(SchedulingPolicyProvider.kt:57)
at org.springframework.kotlin.coroutine.scheduler.DefaultSchedulingPolicyProvider$FIXED_DELAY_STRING_POLICY_CREATOR$1.invoke(SchedulingPolicyProvider.kt:105)
at org.springframework.kotlin.coroutine.scheduler.DefaultSchedulingPolicyProvider$FIXED_DELAY_STRING_POLICY_CREATOR$1.invoke(SchedulingPolicyProvider.kt:30)
at org.springframework.kotlin.coroutine.scheduler.DefaultSchedulingPolicyProvider.createSchedulingPolicy(SchedulingPolicyProvider.kt:42)
I'm trying to set up a basic spring-boot project and I have the following setup:
kotlinVersion = '1.2.70'
classpath("org.jetbrains.kotlin:kotlin-allopen:${kotlinVersion}")
I use the following dependencies:
compile "org.jetbrains.kotlinx:kotlinx-coroutines-core:0.26.1"
compile 'org.springframework.kotlin:spring-kotlin-coroutine:0.3.6'
And here is what I have:
@SpringBootApplication
@EnableCoroutine
class SimpleApplication
fun main(args: Array<String>) {
runApplication<SimpleApplication>(*args)
}
@RestController
class ExampleController {
@GetMapping("sample")
suspend fun sample(): Int {
log.info("In sample")
delay(1000)
log.info("In simple - after delay")
return 1234
}
}
When I hit the endpoint I get the following exception:
kotlin.KotlinNullPointerException: null
at kotlin.coroutines.experimental.jvm.internal.CoroutineImpl.getFacade(CoroutineImpl.kt:36) ~[kotlin-stdlib-1.2.70.jar:1.2.70-release-54 (1.2.70)]
at kotlin.coroutines.experimental.jvm.internal.CoroutineIntrinsics.normalizeContinuation(CoroutineIntrinsics.kt:18) ~[kotlin-stdlib-1.2.70.jar:1.2.70-release-54 (1.2.70)]
at kotlinx.coroutines.experimental.DelayKt.delay(Delay.kt:102) ~[kotlinx-coroutines-core-0.26.1.jar:na]
at kotlinx.coroutines.experimental.DelayKt.delay(Delay.kt:72) ~[kotlinx-coroutines-core-0.26.1.jar:na]
at com.wetransfer.elephant.ExampleController.sample$suspendImpl(ElephantApplication.kt:25) ~[classes/:na]
at com.wetransfer.elephant.ExampleController.sample(ElephantApplication.kt) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_171]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_171]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_171]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_171]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
....
When I comment out the delay(1000)
line it returns the result nicely.
I would like to ask - am I doing something wrong?
Thanks!
How does using coroutines pair with ThreadLocal variables used in Spring? Transactionality, security, MDC etc? What is the best approach to deal with that?
kotlin-reflect
seems not super lenient with the KClass
based @ConditionalOnClass
variant shipped with spring-kotlin-coroutine
, it throws TypeNotPresentException
when for example RxJava is not on the classpath.
To reproduce the issue, comment these 2 RxJava dependencies on my sample Spring + Coroutine app.
I suggest using regular Class
based @ConditionalOnClass
for now, and raising an issue about that on https://youtrack.jetbrains.com/issues/KT in order to be more defensive about that on kotlin-reflect
.
Parameter specified as non-null is null: method org.springframework.kotlin.experimental.coroutine.web.CompletableFutureContinuation.resume, parameter value
at org.springframework.kotlin.experimental.coroutine.web.CompletableFutureContinuation.resume(CoroutinesWebFluxConfigurer.kt)
Are there any plans to migrate to the latest Kotlin release now that coroutines are no longer 'experimental'
Currently I am working on a Spring Boot/Kotlin Coroutines project, but it seems Spring lack of a lot of Coroutines feature provided in this project.
Hi;
I'm trying to use Pageable with the CoroutineMongoRepository.
...
suspend fun findByName(name: String, pageable : Pageable): Page
...
This throws an error on startup from CoroutineMongoQueryMethod:
Method has to use a either multi-item reactive wrapper return type or a wrapped Page/Slice type. Offending method: %s",
How exactly are you expecting it to be wrapped?
I'm not sure if I'm doing something wrong with my setup, or if the coroutines API has changed since this library was last updated, but I'm having some trouble. When I try using a coroutine handler in my controller, I get the error No primary or default constructor found for interface kotlin.coroutines.experimental.Continuation
. Here is the stack trace:
java.lang.NoSuchMethodException: kotlin.coroutines.experimental.Continuation.<init>()
at java.lang.Class.getConstructor0(Class.java:3082) ~[na:1.8.0_141]
at java.lang.Class.getDeclaredConstructor(Class.java:2178) ~[na:1.8.0_141]
at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.createAttribute(ModelAttributeMethodProcessor.java:209) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor.createAttribute(ServletModelAttributeMethodProcessor.java:84) ~[spring-webmvc-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:132) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:124) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:161) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:131) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) ~[spring-webmvc-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:870) ~[spring-webmvc-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:776) ~[spring-webmvc-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991) ~[spring-webmvc-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925) ~[spring-webmvc-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:978) ~[spring-webmvc-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:870) ~[spring-webmvc-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:635) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:855) ~[spring-webmvc-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.5.28.jar:8.5.28]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) ~[tomcat-embed-core-8.5.28.jar:8.5.28]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.28.jar:8.5.28]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:496) [tomcat-embed-core-8.5.28.jar:8.5.28]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.28.jar:8.5.28]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) [tomcat-embed-core-8.5.28.jar:8.5.28]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.28.jar:8.5.28]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [tomcat-embed-core-8.5.28.jar:8.5.28]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803) [tomcat-embed-core-8.5.28.jar:8.5.28]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.28.jar:8.5.28]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790) [tomcat-embed-core-8.5.28.jar:8.5.28]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459) [tomcat-embed-core-8.5.28.jar:8.5.28]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.28.jar:8.5.28]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_141]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_141]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.28.jar:8.5.28]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_141]
And here's my application:
package com.example.demo
import kotlinx.coroutines.experimental.delay
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.kotlin.experimental.coroutine.EnableCoroutine
import org.springframework.kotlin.experimental.coroutine.annotation.Coroutine
import org.springframework.kotlin.experimental.coroutine.context.COMMON_POOL
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
@SpringBootApplication
@EnableCoroutine
open class DemoApplication
fun main(args: Array<String>) {
runApplication<DemoApplication>(*args)
}
@RestController
@Coroutine(COMMON_POOL)
open class FooHandler {
@RequestMapping("/foo")
suspend open fun bar(): String {
delay(100L)
return "foo"
}
}
Is there something else that I need to do in the configuration class, or is this an issue with spring-kotlin-coroutine? Thanks for any help!
I'm using Spring 4.3.9 and spring-kotlin-coroutine 0.2.2. What I want to achieve is make spring @Cacheable annotation work with suspend function, but I got the exception below:
java.lang.ClassCastException: org.springframework.kotlin.experimental.coroutine.cache.CoroutineSuspendedException cannot be cast to org.springframework.cache.interceptor.CacheOperationInvoker$ThrowableWrapper
at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:374)
at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:327)
at org.springframework.kotlin.experimental.coroutine.cache.CoroutineCacheInterceptor.executeCoroutine(CoroutineCacheConfiguration.kt:112)
at org.springframework.kotlin.experimental.coroutine.cache.CoroutineCacheInterceptor.invokeCoroutine(CoroutineCacheConfiguration.kt:100)
at org.springframework.kotlin.experimental.coroutine.cache.CoroutineCacheInterceptor.invoke(CoroutineCacheConfiguration.kt:83)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)
at com.alibaba.intl.trade.delivery.biz.external.fund.FundServiceGatewayImpl$$EnhancerBySpringCGLIB$$9570d4ab.getNysePaymentFulfilled(<generated>)
at com.alibaba.intl.trade.delivery.biz.service.impl.DeliveryReadServiceImpl$prefetchShipmentTermAndPayData$paymentFulfilled$1.doResume(DeliveryReadServiceImpl.kt:318)
at com.alibaba.intl.trade.delivery.biz.service.impl.DeliveryReadServiceImpl$prefetchShipmentTermAndPayData$paymentFulfilled$1.invoke(DeliveryReadServiceImpl.kt)
at com.alibaba.intl.trade.delivery.biz.service.impl.DeliveryReadServiceImpl$prefetchShipmentTermAndPayData$paymentFulfilled$1.invoke(DeliveryReadServiceImpl.kt:43)
at com.alibaba.intl.trade.delivery.biz.util.CoroutineUtilKt$async$1.doResume(CoroutineUtil.kt:28)
at kotlin.coroutines.experimental.jvm.internal.CoroutineImpl.resume(CoroutineImpl.kt:54)
at kotlinx.coroutines.experimental.DispatchedTask$DefaultImpls.run(Dispatched.kt:162)
at kotlinx.coroutines.experimental.DispatchedContinuation.run(Dispatched.kt:26)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1147)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:622)
at java.lang.Thread.run(Thread.java:834)
I just tried to convert one of my CrudRepository
s to CoroutineCrudRepository
.
During boot, my application throws the following error:
Caused by: org.springframework.data.mapping.PropertyReferenceException: No property 'count' found for type 'WorkerState'!
at org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.java:90)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:437)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:413)
at org.springframework.data.mapping.PropertyPath.lambda$from$0(PropertyPath.java:366)
at java.base/java.util.concurrent.ConcurrentMap.computeIfAbsent(ConcurrentMap.java:330)
at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:348)
at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:331)
at org.springframework.data.repository.query.parser.Part.<init>(Part.java:81)
at org.springframework.data.repository.query.parser.PartTree$OrPart.lambda$new$0(PartTree.java:249)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177)
at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
at org.springframework.data.repository.query.parser.PartTree$OrPart.<init>(PartTree.java:250)
at org.springframework.data.repository.query.parser.PartTree$Predicate.lambda$new$0(PartTree.java:383)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177)
at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
at org.springframework.data.repository.query.parser.PartTree$Predicate.<init>(PartTree.java:384)
at org.springframework.data.repository.query.parser.PartTree.<init>(PartTree.java:92)
at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.<init>(PartTreeJpaQuery.java:89)
... 55 common frames omitted
Neither my entity nor my repository ever mentions the term "count", except from a property named crashCount
.
So, I do not try to override count()
or anything like that.
Converting back to plain CrudRepository
solves the problem.
I am using org.springframework.boot:spring-boot-starter-data-jpa
Version 2.6.4
and PostgressDB.
Please find bellow extensions that I had to create, I think these 2 methods should be available by default.
inline suspend fun <reified T : Any> CoroutineWebClient.CoroutineResponseSpec.body() = body(T::class.java)
fun CoroutineWebClient.RequestHeadersUriSpec<*>.uri(uri: String) = uri(URI(uri))
Build:
...
plugins {
id("org.springframework.boot") version "2.1.5.RELEASE"
id("io.spring.dependency-management") version "1.0.7.RELEASE"
kotlin("jvm") version "1.3.31"
kotlin("plugin.spring") version "1.3.31"
}
...
dependencies {
implementation("org.springframework.boot:spring-boot-starter-data-mongodb-reactive")
implementation("org.springframework.boot:spring-boot-starter-webflux")
implementation("org.springframework.kotlin:spring-webflux-kotlin-coroutine:0.3.7")
implementation("org.springframework.kotlin:spring-data-mongodb-kotlin-coroutine:0.3.7")
implementation("org.springframework.kotlin:spring-boot-autoconfigure-kotlin-coroutine:0.3.7")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.0-M1")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor:1.3.0-M1")
}
...
Application configuration:
@Configuration
@EnableCoroutine
@EnableCoroutineMongoRepositories
class ApplicationConfiguration
Controller:
@Document(collection = "person")
data class Person(@Id val id: String? = null, val name: String)
interface PersonRepository : CoroutineMongoRepository<Person, String>
data class PersonForm(val name: String)
@RestController
@RequestMapping("/persons")
class PersonController(private val personRepository: PersonRepository) {
@GetMapping
suspend fun find(): List<Person> = personRepository.findAll()
@PostMapping
suspend fun create(@RequestBody form: PersonForm): Person = personRepository.save(Person(name = form.name))
}
When I send either GET or POST request, server responds with "COROUTINE_SUSPENDED":
GET http://localhost:8080/persons
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Content-Length: 21
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1 ; mode=block
Referrer-Policy: no-referrer
"COROUTINE_SUSPENDED"
Response code: 200 (OK); Time: 9ms; Content length: 21 bytes
It looks like a problem with webflux coroutine because data are stored to database.
As discussed on SPR-15413, and based on your experiment on MiXiT application, any chance you could provide Coroutine based alternative to Spring WebFlux Reactive APIs? That would be especially a good fit with Kotlin server DSL and WebClient
.
I've tried to use suspend modifier to my @GetMapping
in @RestController
as regular suspend function and got an error.
@RestController
@RequestMapping("/api/test")
class TestAPI {
@GetMapping("/wait")
suspend fun wait(): ResponseEntity<*> {
delay(100)
return ResponseEntity.ok("OK")
}
}
and tried to access it via http://localhost:8080/api/test/wait
and got an exception on delay(100)
line:
kotlin.KotlinNullPointerException
at kotlin.coroutines.experimental.jvm.internal.CoroutineImpl.getFacade(CoroutineImpl.kt:48)
at kotlin.coroutines.experimental.jvm.internal.CoroutineIntrinsics.normalizeContinuation(CoroutineIntrinsics.kt:29)
at kotlinx.coroutines.experimental.DelayKt.delay(Delay.kt:129)
at kotlinx.coroutines.experimental.DelayKt.delay(Delay.kt:88)
at com.avant.api.TestAPI.wait$suspendImpl(TestAPI.kt:27)
at com.avant.api.TestAPI.wait(TestAPI.kt)
at sun.reflect.GeneratedMethodAccessor129.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:877)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:866)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:496)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
in pom.xml I've imported
<dependency>
<groupId>org.springframework.kotlin</groupId>
<artifactId>spring-kotlin-coroutine</artifactId>
<version>0.3.4</version>
</dependency>
@EnableCoroutine
is in WebMVCConfigurer,
coroutines-core version is 0.22.5, Kotlin version is 1.2.31, Spring Boot and WebFlux version are 2.0.1.RELEASE. All is running on Windows 10 x64, LTSB.
What am I doing wrong?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.