Kotlin coroutine support for Spring.

Overview

Build status Download Awesome Kotlin Badge

spring-kotlin-coroutine is a repository that contains several libraries and a demo app which allows using Kotlin coroutines in Spring applications as first-class citizens.

Project modules

This project contains several modules:

  1. spring-kotlin-coroutine - a library which allow using Kotlin coroutines in Spring applications. It contains support for @Coroutine annotation, application events, caching, scheduled tasks, CoroutineRestOperations, DeferredRestOperations, ListenableFuture extensions.
  2. spring-webmvc-kotlin-coroutine - a library which allow using Kotlin coroutines in Spring MVC applications. It contains support for web methods.
  3. spring-webflux-kotlin-coroutine - a library which allow using Kotlin coroutines in Spring Web Flux applications. It contains support for Web Flux web methods, CoroutineWebClient and functional style routes definition.
  4. spring-data-mongodb-kotlin-coroutine - a library which allow using Kotlin coroutines in Spring Data Mongo applications. It contains support for CoroutineMongoRepository and CoroutineMongoTemplate.
  5. spring-boot-autoconfigure-kotlin-coroutine - a library which contains autoconfiguration support for spring-data-mongodb-kotlin-coroutine via @EnableCoroutineMongoRepositories annotation.
  6. spring-kotlin-coroutine-demo - contains a sample application which demonstrates the use of spring-kotlin-coroutine and spring-webmvc-kotlin-coroutine.

Supported features

Most of the supported features require adding an @EnableCoroutine annotation to your Spring @Configuration class.

@EnableCoroutine

This annotation enables using the features described below. If it is possible to use a feature without this annotation it is explicitly stated so in the feature description. The annotation can be used as follows:

@Configuration
@EnableCoroutine(
    proxyTargetClass = false, mode = AdviceMode.PROXY, 
    order = Ordered.LOWEST_PRECEDENCE, schedulerDispatcher = "")
open class MyAppConfiguration {
 ...
}

The proxyTargetClass, mode and order attributes of @EnableCoroutine follow the same semantics as @EnableCaching. schedulerDispatcher is a CoroutineDispatcher used to run @Scheduled corroutines.

Note that currently only AdviceMode.PROXY mode is supported.

Web methods

Because coroutines can be suspended and they have an additional implicit callback parameter they cannot be used as web methods by default. With special parameter and result handling introduced in spring-webmvc-kotlin-coroutine you can safely use coroutines as web methods. You can e.g. have the following component:

@RestController
open class MyController {
    @GetMapping("/customers")
    suspend open fun getCustomers(): List<Customer> {
       ...
    }
}

@Coroutine

Spring beans and its methods can be annotated with @Coroutine. Using this annotation you can specify the coroutine context via the context attribute and the coroutine name via the name attribute. The context specifies a name of a bean from which a CoroutineContext can be created. Currently the following contexts/bean types are supported:

  1. CoroutineContext type beans - used directly
  2. DEFAULT_DISPATCHER - a constant specifying the Dispatchers.Default context
  3. UNCONFINED - a constant specifying the Dispatchers.Unconfined context
  4. Executor type beans - converted to CoroutineContext with asCoroutineDispatcher
  5. Rx2 Scheduler type beans - converted to CoroutineContext with asCoroutineDispatcher
  6. Reactor Scheduler type beans - converted to CoroutineContext with asCoroutineDispatcher
  7. TaskScheduler type beans - converted to CoroutineContext with asCoroutineDispatcher method of TaskSchedulerCoroutineContextResolver

You can also support your own types of beans or context names by providing Spring beans of type CoroutineContextResolver:

interface CoroutineContextResolver {
    fun resolveContext(beanName: String, bean: Any?): CoroutineContext?
}

Using @Coroutine it is quite easy to achieve the same effect as with @Async, although the code will look much simpler:

@RestController
open class MyController(
    private val repository: MyRepository
) {
    @GetMapping("/customers")
    suspend open fun getCustomers(): List<Customer> {
       return repository.getAllCustomers()
    }
}

@Component
@Coroutine(DEFAULT_DISPATCHER)
open class MyRepository {
    suspend open fun getAllCustomers(): List<Customer> {
      // a blocking code
      // which will be run with DEFAULT_DISPATCHER context
      // or simply ForkJoinPool
      ...
    }
}

Application events

Spring allows you to decouple senders and receivers of application events with the usage of ApplicationEventPublisher and @EventListener methods. They cannot, however, be coroutines. spring-kotlin-coroutine allows you to send events in a way that allows the suspension of event processing. You can also have an @EventListener method which is a coroutine.

For sending a component with the following interface can be used:

interface CoroutineApplicationEventPublisher {
    suspend fun publishEvent(event: ApplicationEvent)

    suspend fun publishEvent(event: Any)
}

Your bean can inject this interface or it can implement a CoroutineApplicationEventPublisherAware interface and have it delivered via a setCoroutineApplicationEventPublisher method:

interface CoroutineApplicationEventPublisherAware : Aware {
    fun setCoroutineApplicationEventPublisher(publisher: CoroutineApplicationEventPublisher)
}

The events sent by either CoroutineApplicationEventPublisher or ApplicationEventPublisher can be received by any method annotated with @EventListener (a coroutine or a regular one). The result of coroutine listeners will be handled in the same way as for regular listeners:

  • if it is a Unit nothing will happen
  • if it returns a single value it will be treated as a newly published event
  • if it returns an array or a collection of values it will be treated as a collection of newly published events

@Cacheable support

Due to an additional callback parameter and a special return value semantics coroutine return values cannot be cached using default Spring caching feature. However with spring-kotlin-coroutine it is possible to use a @Cacheable annotation on a coroutine, e.g.:

@Configuration
@EnableCaching
@EnableCoroutine
open class MyConfiguration {
}

@Component
class MyComponent {
    @Cacheable
    open suspend fun getCustomer(id: String): Customer {
        ...
    }
}

@Scheduled support

Coroutines annotated with @Scheduled will not work with regular Spring. However, with spring-kotlin-coroutine you can use them the same way you would do it with regular methods with the following caveats:

  1. They will be executed using CoroutineDispatcher obtained from:
  2. The exception thrown from the coroutine will be handled using:

CoroutineRestOperations

Spring provides blocking RestOperations to be used as a REST client. spring-kotlin-coroutine provides CoroutineRestOperations interface which has the same methods as RestOperations, but as coroutines:

interface CoroutineRestOperations {
    suspend fun <T : Any?> postForObject(url: String, request: Any?, responseType: Class<T>?, vararg uriVariables: Any?): T

    suspend fun <T : Any?> postForObject(url: String, request: Any?, responseType: Class<T>?, uriVariables: Map<String, *>): T

    suspend fun <T : Any?> postForObject(url: URI, request: Any?, responseType: Class<T>?): T

    ...
}

In order to create CoroutineRestOperations use the following:

val restOps = CoroutineRestOperations(restOperations = RestTemplate(), context = null)
val defaultRestOps = CoroutineRestOperations() 

If you do not specify any arguments when creating CoroutineRestOperations it will delegate all calls to RestTemplate instance and use a special coroutine context which will invoke the blocking method of RestTemplate on a separate thread (just like AsyncRestTemplate). You can specify your own RestOperations and CoroutineContext to change that behaviour.

Note that CoroutineRestOperations does not need @EnableCoroutine in order to work. Underneath CoroutineRestOperations uses createCoroutineProxy.

DeferredRestOperations

The kotlinx.coroutines library provides Deferred<T> type for non-blocking cancellable future. Based on that spring-kotlin-coroutine provides DeferredRestOperations interface which has the same methods as RestOperations, but with Deferred<T> return type:

interface DeferredRestOperations {
    fun <T : Any?> postForObject(url: String, request: Any?, responseType: Class<T>?, vararg uriVariables: Any?): Deferred<T>

    fun <T : Any?> postForObject(url: String, request: Any?, responseType: Class<T>?, uriVariables: Map<String, *>): Deferred<T>

    fun <T : Any?> postForObject(url: URI, request: Any?, responseType: Class<T>?): Deferred<T>

    ...
}

In order to create DeferredRestOperations use the following:

val restOps = DeferredRestOperations(restOperations = RestTemplate(), start = CoroutineStart.DEFAULT, context = COMMON_POOL)
val defaultRestOps = DeferredRestOperations() 

If you do not specify any arguments when creating DeferredRestOperations it will delegate all calls to RestTemplate instance and use a special coroutine context which will immediately invoke the blocking method of RestTemplate on a separate thread (just like AsyncRestTemplate). You can specify your own RestOperations and CoroutineContext to change that behaviour. By changing the start parameter value you can specify when the REST operation should be invoked (see CoroutineStart for details).

Note that DeferredRestOperations does not need @EnableCoroutine in order to work. Underneath DeferredRestOperations uses createCoroutineProxy.

Web Flux web methods

By using spring-webflux-kotlin-coroutine module instead of spring-webmvc-kotlin-coroutine web methods which are suspending functions will use Spring Web Flux. This enables them to use non-blocking I/O API.

CoroutineWebClient

CoroutineWebClient is a counterpart of the Spring Web Flux WebClient component. The differences between these components can be found mainly in the functions which operate on reactive types - in CoroutineWebClient they are suspending functions operating on regular types. Also the naming of the methods can be slightly different (e.g. in WebClient you can find bodyToMono and in CoroutineWebClient it is simply body).

Functional style routes definition

TBD

CoroutineMongoRepository

spring-data-mongodb-kotlin-coroutine contains support for CoroutineMongoRepository-based repositories. These repositories work as regular Spring Data Mongo or Spring Data Mongo Reactive repositories, but have support for suspending functions and ReceiveChannel type.

CoroutineMongoTemplate

CoroutineMongoTemplate is a counterpart of regular MongoTemplate, but contains suspending functions instead of regular ones.

EnableCoroutineMongoRepositories

The @EnableCoroutineMongoRepositories annotation works just like @EnableMongoRepositories annotation, but enables the usage of CoroutineMongoRepository repositories.

ListenableFuture extensions

The kotlinx.coroutines library provides interoperability functions with many existing asynchronous libraries ( RxJava v1, RxJava v2, CompletableFuture, etc.). However, there is no support for Spring specific ListenableFuture interface. Therefore spring-kotlin-coroutine provides the following features:

  1. fun <T> listenableFuture(context: CoroutineContext = DefaultDispatcher, block: suspend () -> T): ListenableFuture<T> - it allows you to create a ListenableFuture from a coroutine with specific coroutine context.
  2. fun <T> Deferred<T>.asListenableFuture(): ListenableFuture<T> - it allows you to create a ListenableFuture from Kotlin coroutine specific Deferred type.
  3. suspend fun <T> ListenableFuture<T>.await(): T - it allows you to create a coroutine from a ListenableFuture.

Note that these extensions do not need @EnableCoroutine in order to work.

Utility functions

Note that utility functions do not need @EnableCoroutine in order to work.

createCoroutineProxy

createCoroutineProxy can be used to create a smart proxy - an instance of an interface which will delegate all function invocations to a regular object with matching method signatures. The runtime characteristics of this proxy call depends on the types of the interface methods, the types of the proxied object methods and the proxy config. The createCoroutineProxy is declared as follows:

fun <T: Any> createCoroutineProxy(coroutineInterface: Class<T>, obj: Any, proxyConfig: CoroutineProxyConfig): T

Currently supported proxy types are as follows:

Coroutine interface method Object method Proxy config
suspend fun m(a: A): T fun m(a: A): T DefaultCoroutineProxyConfig
fun <T> m(a: A): Deferred<T> fun m(a: A): T DeferredCoroutineProxyConfig

Method.isSuspend

Method.isSuspend allows you to check if a method is a coroutine. It is defined as follows:

val Method.isSuspend: Boolean

Using in your projects

Note that this library is experimental and is subject to change.

The library is published to konrad-kaminski/maven Bintray repository.

Gradle

Add Bintray repository:

repositories {
  maven { url 'https://dl.bintray.com/konrad-kaminski/maven' }
}

Add dependencies:

compile 'org.springframework.kotlin:spring-kotlin-coroutine:0.3.7'

Note that some of the dependencies of spring-kotlin-coroutine are declared as optional. You should declare them as runtime dependencies of your application if you want to use the features that require them. The table below contains the details:

Feature Dependency
Web methods org.springframework:spring-webmvc:5.0.9.RELEASE
Rx2 Scheduler in @Coroutine org.jetbrains.kotlinx:kotlinx-coroutines-rx2:1.2.1
Reactor Scheduler in @Coroutine org.jetbrains.kotlinx:kotlinx-coroutines-reactor:1.2.1

And make sure that you use the right Kotlin version:

buildscript {
    ext.kotlin_version = '1.3.30'
}

FAQ

Why all the methods/classes have "Coroutine" as part of its name and not "Suspending"?

It's a deliberate choice. In most cases Coroutine just sounded better to me and even though sometimes Suspending might've been a better choice for consistency Coroutine was used.

License

spring-kotlin-coroutine is released under version 2.0 of the Apache License.

Comments
  • Bean validation does not work on a coroutine controller

    Bean validation does not work on a coroutine controller

    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]
    
    opened by sagacity 5
  • Support for Kotlin 1.3.0

    Support for Kotlin 1.3.0

    This pull request includes:

    • Most of changes are modifying kotlin.coroutines, kotlinx.coroutines related package names
    • No longer supports RxJava 1.x in kotlinx.coroutines, therefore I've removed RxJava 1.x supports.
    • Apply Continuation<T>'s method changes ( resume, resumeWithException -> resumeWith)
    opened by 0mok 4
  • Demo - Utils.kt means companion objects not allowed in Spring Component?

    Demo - Utils.kt means companion objects not allowed in Spring Component?

    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!")
    }
    

    ...

    opened by bdueck 4
  • spring security context not propagated

    spring security context not propagated

    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)
    }
    
    opened by userquin 3
  • Error creating bean with name 'coroutineAnnotationBeanPostProcessor'

    Error creating bean with name 'coroutineAnnotationBeanPostProcessor'

    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
    
    opened by breun 3
  • Add Coroutine based alternative to Reactive Spring WebFlux APIs

    Add Coroutine based alternative to Reactive Spring WebFlux APIs

    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.

    opened by sdeleuze 3
  • Support for Kotlin 1.3.21 and coroutines 1.1.1

    Support for Kotlin 1.3.21 and coroutines 1.1.1

    Update changes from https://github.com/konrad-kaminski/spring-kotlin-coroutine/pull/40 to ext.kotlin_version 1.3.21 and kotlin_coroutines_version 1.1.1

    opened by domgom 2
  • java.lang.ClassNotFoundException: kotlinx.coroutines.experimental.Dispatchers

    java.lang.ClassNotFoundException: kotlinx.coroutines.experimental.Dispatchers

    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
    
    opened by VikaChebotar 2
  • Getting NullPointerException Question

    Getting NullPointerException Question

    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!

    opened by mitrejcevski 2
  • Unwrap InvocationTargetException on DeferredRestOperations

    Unwrap InvocationTargetException on DeferredRestOperations

    I think DeferredRestOperations should return same exceptions as original RestOperations, so they can be used as drop in replacement.

    Probably this change should be also applied for CoroutineRestOperations, but I wanted to know your opinion first.

    opened by Krotki 2
  • Suspendable controller methods returning ResponseEntity are not handled

    Suspendable controller methods returning ResponseEntity are not handled

    https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html#webflux-ann-responseentity

    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))
        }
    }
    
    opened by fabienmoritz 2
  • CoroutineCrudRepository throws PropertyReferenceException for count method

    CoroutineCrudRepository throws PropertyReferenceException for count method

    I just tried to convert one of my CrudRepositorys 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.

    opened by alkismavridis 1
  • Any update of this project?

    Any update of this project?

    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.

    1. Couroutines Beans in Configuration
    2. Coroutines aware event, cache, scheduler, etc.
    3. No Coroutines Template in Spring Data, only provides CoroutinesRepository.
    4. Spring Security does not provides Coroutines support its components(such as Security DSL, etc).
    opened by hantsy 0
  • Bintray sunset, can't download dependency

    Bintray sunset, can't download dependency

    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?

    opened by MaxwellPayne 8
  • fixedDelayString error - embeddedValueResolver null in DefaultSchedulingPolicyProvider

    fixedDelayString error - embeddedValueResolver null in DefaultSchedulingPolicyProvider

    @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)
    
    
    opened by vklidu 0
  • the Java method #CoroutineUtils.runCoroutine doesn't work

    the Java method #CoroutineUtils.runCoroutine doesn't work

    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!!!
    opened by cherrythefatbunny 0
Owner
Konrad Kamiński
Konrad Kamiński
Reactive setup with Spring WebFlux , Kotlin, Postgres and Spring Data R2DBC

Reactive Spring with Kotlin and Pg Spring WebFlux with Netty instead of Spring Web with Tomcat Mono and Flux in all layers (controller, service, repo)

Bimal Raj Gyawali 7 Dec 9, 2022
This repository contains RabbitMQ Protobuf starters with its usage samples for spring-rabbit and spring-cloud-starter-stream-rabbit modules

This repository contains RabbitMQ Protobuf starters with its usage samples for spring-rabbit and spring-cloud-starter-stream-rabbit modules

Maksim Kostromin 2 Nov 29, 2021
Spring-with-maven - Spring Boot App with Postgresql and maven

Spring Boot Api Aplikasi ini dibuat menggunakan bahasa kotlin dan untuk database

Aldi Aulia Rosyad 1 Jan 12, 2022
Android login spring - Android login against spring backend

Android Jetpack Compose login implementation with JWT tokens against our own bac

null 1 Feb 13, 2022
New Relic Kotlin Instrumentation for Kotlin Coroutine. It successfully handles thread changes in suspend states.

new-relic-kotlin-coroutine New Relic Kotlin Instrumentation for Kotlin Coroutine. It successfully handles thread changes in suspend states. Usage 1- U

Mehmet Sezer 7 Nov 17, 2022
Android Multi Theme Switch Library ,use kotlin language ,coroutine ,and so on ...

Magic Mistletoe Android多主题(换肤)切换框架 背景 时隔四年,在网易换肤之前的思路下,做了几点改进,现在完全通过反射创建View,并且在SkinLoadManager中提供一个configCustomAttrs以支持自定义View的属性插队替换 摈弃了之前的AsyncTask

Mistletoe 18 Jun 17, 2022
R2DBC Sharding Example with Kotlin Coroutine

R2DBC Sharding Example with Kotlin Coroutine A minimal sharding example with R2DBC and coroutine, where user table is divided into 2 different shards.

K.S. Yim 0 Oct 4, 2021
Kreds - a thread-safe, idiomatic, coroutine based Redis client written in 100% Kotlin

Kreds Kreds is a thread-safe, idiomatic, coroutine based Redis client written in 100% Kotlin. Why Kreds? Kreds is designed to be EASY to use. Kreds ha

Abhijith Shivaswamy 117 Dec 23, 2022
Demonstration of Object Pool Design Pattern using Kotlin language and Coroutine

Object Pool Design Pattern with Kotlin Demonstration of Thread Safe Object Pool Design Pattern using Kotlin language and Coroutine. Abstract The objec

Enes Kayıklık 7 Apr 12, 2022
🚀 🥳 MVVM based sample currency converter application using Room, Koin, ViewModel, LiveData, Coroutine

Currency Converter A demo currency converter app using Modern Android App Development techniques Tech stack & Open-source libraries Minimum SDK level

Abinash Neupane 2 Jul 17, 2022
MVVM ,Hilt DI ,LiveData ,Flow ,SharedFlow ,Room ,Retrofit ,Coroutine , Navigation Component ,DataStore ,DataBinding , ViewBinding, Coil

RickMorty This is a simple app which has been implemented using Clean Architecture alongside MVVM design to run (online/offline) using : [ MVVM ,Hilt

Ali Assalem 13 Jan 5, 2023
A sample skeleton backend app built using Spring Boot kotlin, Expedia Kotlin Graphql, Reactive Web that can be deployed to Google App Engine Flexible environmennt

spring-kotlin-gql-gae This is a sample skeleton of a backend app that was built using: Spring Boot(Kotlin) Reactive Web Sprinng Data R2DBC with MYSQL

Dario Mungoi 7 Sep 17, 2022
Spring Boot Example with Kotlin and Domain Driven Design

Spring Boot Kotlin Domain Driven Design Example Just an example project where ddd is implemented with some other great patterns and architecture from

Fernando Guevara Sanchez 16 Jun 29, 2022
Sample Social Login Project of Spring Boot and Kotlin

Sample-Spring-Boot-Social-Kotlin Sample Social Login Project of Spring Boot and Kotlin dependencies dependencies { implementation("org.springframewor

Seokhyun 2 Oct 11, 2021
This repository demonstrates how Kotlin can simplify Spring Boot configuration properties file mapping

Kotlin spring-boot nested config props This repository demonstrates how Kotlin can simplify Spring Boot configuration properties file mapping @Constru

Maksim Kostromin 1 Oct 11, 2021
Generated with spring boot kotlin starter kit

Kotlin backend Generated with spring boot kotlin starter kit The idea is to: Get a microservice written in kotlin for managing users and roles. To be

Oriol Subirana 1 Oct 19, 2021
The Okila server project uses the Spring boot framework and uses the Kotlin language

Okila-Server The Okila server project uses the Spring boot framework and uses the Kotlin language Format Response //The response successfully format

Nankai 1 Oct 25, 2021
An application that simulate the Swedish Transport Agency, implemented with Spring Boot, Kotlin and GraphQL

graphql-kotlin-spring-server An application that simulate the Swedish Transport Agency, implemented with Spring Boot, Kotlin and GraphQL Running the s

null 0 Oct 31, 2021
API for a library using Kotlin, Spring-boot and covered by test

Library API This API is to create Books and be able to borrow from them I'm using: Spring Boot version 2.5.6 Kotlin 1.5.31 Java 11 I'm implementing us

Daniel Queiroz 1 Nov 5, 2021