Skip to content

Example of kotlin version with service proxy #28

Open

Description

@xurshid29

Hi, can anybody provide kotlin version of this tutorial with service proxies? I couldn't manage it to work;

Every time I get such error on build:

build/tmp/kapt3/stubs/main/uz/craftier/database/WikiDatabaseService.java:46: error: Could not generate model for uz.craftier.database.WikiDatabaseService.Companion: @VertxGen can only be used with interfaces or enums in uz.craftier.database.WikiDatabaseService.Companion

Here is my interface:
screen shot 2018-01-13 at 2 09 58 pm

And, added kapt plugin to build.gradle:

apply plugin: 'kotlin-kapt'

dependencies {
    ...
    kapt "io.vertx:vertx-codegen:$vertx_version:processor"
    compileOnly "io.vertx:vertx-codegen:$vertx_version"
    ...
}

Activity

  1. abelhegedus commented on Feb 28, 2018

    @abelhegedus

    I ran into the same issue when experimenting with service proxies.
    The problematic part is the companion object, which trips up the annotation generator.

    A possible workaround:

    @ProxyGen
    @VertxGen
    interface MyService {
        fun myMethod(param: String)
    }
    
    object MyServiceFactory {
        fun create(vertx: Vertx): MyService{
            return MyServiceImpl(vertx)
        }
        fun createProxy(vertx: Vertx, address: String, options: DeliveryOptions = DeliveryOptions()): MyService {
            return MyServiceVertxEBProxy(vertx, address, options)
        }
    }
  2. desmondtzq commented on Jun 18, 2018

    @desmondtzq

    Is it also possible to generate the rx version of the proxy?

  3. mustafakibar commented on Jun 21, 2018

    @mustafakibar

    I have the same problem on rx version of the service proxy..

  4. desdulianto commented on Aug 7, 2018

    @desdulianto

    I also get the same problem, and then based on @abelhegedus' idea, here my workaround:

    @ProxyGen
    interface WikiDatabaseService {
    
        @Fluent
        fun fetchAllPages(resultHandler: Handler<AsyncResult<JsonArray>>): WikiDatabaseService
    
        @Fluent
        fun fetchPage(name: String, resultHandler: Handler<AsyncResult<JsonObject>>): WikiDatabaseService
    
        @Fluent
        fun createPage(title: String, markdown: String, resultHandler: Handler<AsyncResult<Void>>): WikiDatabaseService
    
        @Fluent
        fun savePage(id: Int, markdown: String, resultHandler: Handler<AsyncResult<Void>>): WikiDatabaseService
    
        @Fluent
        fun deletePage(id: Int, resultHandler: Handler<AsyncResult<Void>>): WikiDatabaseService
    
        @GenIgnore
        companion object {
            fun create(dbClient: JDBCClient, sqlQueries: Map<SqlQuery, String>,
                       readyHandler: Handler<AsyncResult<WikiDatabaseService>>): WikiDatabaseService =
                    WikiDatabaseServiceImpl(dbClient, sqlQueries, readyHandler)
    
            fun createProxy(vertx: Vertx, address: String): WikiDatabaseService =
                    WikiDatabaseServiceVertxEBProxy(vertx, address)
        }
    }

    I added @GenIgnore annotation on companion object because kapt keeps complaining about Map<SqlQuery, String> and JDBCClient are not legal types.

  5. rgmz commented on Aug 9, 2018

    @rgmz

    @desmondtzq @mustafakibar To my knowledge there is no way to do this in 1.2.x as interfaces are not allowed to have @JvmStatic members.

    However, support for this is added in 1.3 (https://youtrack.jetbrains.com/issue/KT-6301) meaning that the following should work:

    @ProxyGen
    interface WikiDatabaseService {
    
        @Fluent
        fun fetchAllPages(resultHandler: Handler<AsyncResult<JsonArray>>): WikiDatabaseService
    
        @Fluent
        fun fetchPage(name: String, resultHandler: Handler<AsyncResult<JsonObject>>): WikiDatabaseService
    
        @Fluent
        fun createPage(title: String, markdown: String, resultHandler: Handler<AsyncResult<Void>>): WikiDatabaseService
    
        @Fluent
        fun savePage(id: Int, markdown: String, resultHandler: Handler<AsyncResult<Void>>): WikiDatabaseService
    
        @Fluent
        fun deletePage(id: Int, resultHandler: Handler<AsyncResult<Void>>): WikiDatabaseService
    
        @GenIgnore
        companion object {
            @JvmStatic
            fun create(dbClient: JDBCClient, sqlQueries: Map<SqlQuery, String>,
                       readyHandler: Handler<AsyncResult<WikiDatabaseService>>): WikiDatabaseService =
                    WikiDatabaseServiceImpl(dbClient, sqlQueries, readyHandler)
    
            @JvmStatic
            fun createProxy(vertx: Vertx, address: String): WikiDatabaseService =
                    WikiDatabaseServiceVertxEBProxy(vertx, address)
        }
    }
    

    (You can actually use this feature now, as per Michael Bogdanov's comment, though since it's pre-release it's technically not stable.)

  6. raghumulukutla commented on Mar 28, 2019

    @raghumulukutla

    @rgmz , I've tried adding @JvmStatic like you did on Kotlin 1.3.21n and I still have this error ".Companion is not legal for use for a constant type in code generation"

    Any other workarounds that you might suggest?

  7. rgmz commented on Mar 28, 2019

    @rgmz

    @raghumulukutla A change introduced in Vert.x 3.6.x inadvertently broke this.

    I created a pull request to fix this—hopefully it makes it into the next release, or a viable workaround is provided.


    @gmariotti do you have any suggested workarounds to mimic this behaviour?

  8. gmariotti commented on Mar 28, 2019

    @gmariotti

    @rgmz sorry, I wanted to look into it but I never found the time. With @vietj, we discussed in the past to try to find a solution that wasn't Kotlin specific but I didn't find anything so far

  9. raghumulukutla commented on Mar 28, 2019

    @raghumulukutla

    @gmariotti @rgmz Thanks! I've also tried using a Vertx version < 3.6.x. Reproduces the same error.

  10. rgmz commented on Mar 31, 2019

    @rgmz

    @raghumulukutla Can you provide a reproducer? I do not get the error in version 3.5.4.

    Try this ad-hoc example: https://github.com/rgmz/vertx-kotlin-service-proxy

  11. raghumulukutla commented on Apr 2, 2019

    @raghumulukutla

    @rgmz I'm sorry, I should correct myself. I do not get the same error. But I do get a kaptKotlin error. Here's the reproducer:
    https://github.com/raghumulukutla/vertx-guide-kotlin/tree/service_proxy/src/main/kotlin/com/raghu/vertx3guide/wiki/step3/database

    WikiDatabaseService.kt

    package com.raghu.vertx3guide.wiki.step3.database
    
    import io.vertx.codegen.annotations.Fluent
    import io.vertx.codegen.annotations.GenIgnore
    import io.vertx.codegen.annotations.ProxyGen
    import io.vertx.codegen.annotations.VertxGen
    import io.vertx.core.AsyncResult
    import io.vertx.core.Handler
    import io.vertx.core.Vertx
    import io.vertx.core.json.JsonArray
    import io.vertx.core.json.JsonObject
    import io.vertx.ext.asyncsql.AsyncSQLClient
    
    
    @ProxyGen
    @VertxGen
    interface WikiDatabaseService {
      @Fluent
      fun fetchAllPages(resultHandler: Handler<AsyncResult<JsonArray>>):WikiDatabaseService
    
      @Fluent
      fun fetchPage(name:String,resultHandler: Handler<AsyncResult<JsonObject>>):WikiDatabaseService
    
      @Fluent
      fun createPage(title:String, markdown:String, resultHandler: Handler<AsyncResult<Void>>):WikiDatabaseService
    
      @Fluent
      fun savePage(id:Int, markdown:String,resultHandler: Handler<AsyncResult<Void>>):WikiDatabaseService
    
      @Fluent
      fun deletePage(id:Int, resultHandler: Handler<AsyncResult<Void>>):WikiDatabaseService
    
      @GenIgnore
      companion object {
        @GenIgnore
        @JvmStatic
        fun create(dbClient:AsyncSQLClient, sqlQueries: HashMap<SqlQuery, String>, readyHandler: Handler<AsyncResult<WikiDatabaseService>>):WikiDatabaseService {
          return WikiDatabaseServiceImpl(dbClient, sqlQueries, readyHandler)
    
        }
        @GenIgnore
        @JvmStatic
        fun createProxy(vertx: Vertx, address:String ):WikiDatabaseService {
          return WikiDatabaseServiceVertxEBProxy(vertx, address)
        }
      }
    
    }
    
    

    Error:

    could not generate model for com.raghu.vertx3guide.wiki.step3.database.WikiDatabaseService#create(io.vertx.ext.asyncsql.AsyncSQLClient,java.util.HashMap<com.raghu.vertx3guide.wiki.step3.database.SqlQuery,java.lang.String>,io.vertx.core.Handler<io.vertx.core.AsyncResult<com.raghu.vertx3guide.wiki.step3.database.WikiDatabaseService>>): type java.util.HashMap<com.raghu.vertx3guide.wiki.step3.database.SqlQuery,java.lang.String> is not legal for use for a parameter in code generation
        public static com.raghu.vertx3guide.wiki.step3.database.WikiDatabaseService create(@org.jetbrains.annotations.NotNull()
    
    
  12. liuandong commented on Apr 9, 2019

    @liuandong

    just use java interface in kotlin project

  13. rayfragment commented on Dec 2, 2019

    @rayfragment

    Is extension function a possible workaround? So that we won't need to setup companion object

    @ProxyGen
    interface WikiDatabaseService{
        ...
    }
    
    fun WikiDatabaseService.create(
        dbClient:AsyncSQLClient, 
        sqlQueries: HashMap<SqlQuery, String>, 
        readyHandler: Handler<AsyncResult<WikiDatabaseService>>
    ):WikiDatabaseService = WikiDatabaseServiceImpl(dbClient, sqlQueries, readyHandler)
    fun WikiDatabaseService.createProxy(
        vertx: Vertx, 
        address:String
    ):WikiDatabaseService = WikiDatabaseServiceVertxEBProxy(vertx, address)
    
  14. rgmz commented on Dec 6, 2019

    @rgmz

    Is extension function a possible workaround? So that we won't need to setup companion object

    Unfortunately Kotlin does not support static extension functions; in order to call create you'd need to already have an instance of WikiDatabaseServiceImpl.

    Additionally, non-static methods are not picked up by codegen so you would need to manually define factory methods for everything, e.g. the rxified API.

  15. rgmz commented on May 31, 2021

    @rgmz

    @raghumulukutla A change introduced in Vert.x 3.6.x inadvertently broke this.

    I created a pull request to fix this—hopefully it makes it into the next release, or a viable workaround is provided.

    FYI, once Vert.x 4.1.0 is released this issue should be resolved.

    Try this ad-hoc example: https://github.com/rgmz/vertx-kotlin-service-proxy

    4.1.0 isn't released yet, but this is now updated to 4.1.0.CR2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions