papsign / Ktor-OpenAPI-Generator

Ktor OpenAPI/Swagger 3 Generator
Apache License 2.0
243 stars 42 forks source link

Empty list doesn't contain element at index 0 #26

Closed SerVB closed 4 years ago

SerVB commented 4 years ago

Sometimes when I run tests, I get the following exception for all tests:

Stacktrace ``` java.lang.IndexOutOfBoundsException: Empty list doesn't contain element at index 0. at kotlin.collections.EmptyList.get(Collections.kt:35) at kotlin.collections.EmptyList.get(Collections.kt:23) at com.papsign.ktor.openapigen.schema.builder.provider.DefaultMapSchemaProvider$Builder.build(DefaultMapSchemaProvider.kt:22) at com.papsign.ktor.openapigen.schema.builder.provider.FinalSchemaBuilderProvider$Builder.build(FinalSchemaBuilderProvider.kt:70) at com.papsign.ktor.openapigen.schema.builder.provider.DefaultObjectSchemaProvider$Builder$build$1.invoke(DefaultObjectSchemaProvider.kt:50) at com.papsign.ktor.openapigen.schema.builder.provider.DefaultObjectSchemaProvider$Builder$build$1.invoke(DefaultObjectSchemaProvider.kt:30) at com.papsign.ktor.openapigen.schema.builder.provider.DefaultObjectSchemaProvider$Builder.build(DefaultObjectSchemaProvider.kt:39) at com.papsign.ktor.openapigen.schema.builder.provider.FinalSchemaBuilderProvider$Builder.build(FinalSchemaBuilderProvider.kt:70) at com.papsign.ktor.openapigen.schema.builder.FinalSchemaBuilder$DefaultImpls.build$default(FinalSchemaBuilder.kt:8) at com.papsign.ktor.openapigen.content.type.ktor.KtorContentProvider.getMediaType(KtorContentProvider.kt:63) at com.papsign.ktor.openapigen.modules.handlers.ThrowOperationHandler.configure(ThrowOperationHandler.kt:27) at com.papsign.ktor.openapigen.modules.handlers.RouteHandler.configure(RouteHandler.kt:32) at io.github.servb.eShop.handler.product.v1.CreateProductKt.createProduct(createProduct.kt:169) at io.github.servb.eShop.route.product.v1.AddProductV1RoutesKt.addProductV1Routes(addProductV1Routes.kt:7) at io.github.servb.eShop.ApplicationKt$module$4.invoke(Application.kt:106) at io.github.servb.eShop.ApplicationKt$module$4.invoke(Application.kt) at com.papsign.ktor.openapigen.route.RouteConfigKt$apiRouting$1.invoke(RouteConfig.kt:17) at com.papsign.ktor.openapigen.route.RouteConfigKt$apiRouting$1.invoke(RouteConfig.kt) at io.ktor.routing.RoutingKt.routing(Routing.kt:120) at com.papsign.ktor.openapigen.route.RouteConfigKt.apiRouting(RouteConfig.kt:13) at io.github.servb.eShop.ApplicationKt.module(Application.kt:89) at io.github.servb.eShop.product.InMemoryEShopProductKt.inMemoryEShopProduct(inMemoryEShopProduct.kt:6) at io.github.servb.eShop.product.route.singleOperation.EShopProductCreateProductTest$1$1$1.invoke(EShopProductCreateProductTest.kt:20) at io.github.servb.eShop.product.route.singleOperation.EShopProductCreateProductTest$1$1$1.invoke(EShopProductCreateProductTest.kt:18) at io.ktor.server.testing.TestEngineKt$withTestApplication$1.invoke(TestEngine.kt:67) at io.ktor.server.testing.TestEngineKt$withTestApplication$1.invoke(TestEngine.kt) at io.ktor.server.testing.TestEngineKt.withApplication(TestEngine.kt:49) at io.ktor.server.testing.TestEngineKt.withApplication$default(TestEngine.kt:43) at io.ktor.server.testing.TestEngineKt.withTestApplication(TestEngine.kt:66) at io.github.servb.eShop.util.KotlinFutureKt.withTestApplication(KotlinFuture.kt:13) at io.github.servb.eShop.product.route.singleOperation.EShopProductCreateProductTest$1$1.invokeSuspend(EShopProductCreateProductTest.kt:20) at io.github.servb.eShop.product.route.singleOperation.EShopProductCreateProductTest$1$1.invoke(EShopProductCreateProductTest.kt) at io.kotest.core.spec.style.BehaviorSpecDsl$addGivenContext$1.invokeSuspend(behaviorSpecDsl.kt:25) at io.kotest.core.spec.style.BehaviorSpecDsl$addGivenContext$1.invoke(behaviorSpecDsl.kt) at io.kotest.core.runtime.ExecutionsKt$executeWithTimeout$2$1.invokeSuspend(executions.kt:16) at io.kotest.core.runtime.ExecutionsKt$executeWithTimeout$2$1.invoke(executions.kt) at io.kotest.core.AsserterKt.executeWithGlobalAssertSoftlyCheck(Asserter.kt:37) at io.kotest.core.runtime.ExecutionsKt$executeWithTimeout$2.invokeSuspend(executions.kt:16) at io.kotest.core.runtime.ExecutionsKt$executeWithTimeout$2.invoke(executions.kt) at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturnIgnoreTimeout(Undispatched.kt:102) at kotlinx.coroutines.TimeoutKt.setupTimeout(Timeout.kt:78) at kotlinx.coroutines.TimeoutKt.withTimeout(Timeout.kt:31) at io.kotest.core.runtime.ExecutionsKt.executeWithTimeout--MKxnPQ(executions.kt:13) at io.kotest.core.runtime.TestExecutor$executeAndWait$2$1$3.invokeSuspend(TestExecutor.kt:181) at io.kotest.core.runtime.TestExecutor$executeAndWait$2$1$3.invoke(TestExecutor.kt) at io.kotest.core.runtime.ReplayKt.replay(replay.kt:19) at io.kotest.core.runtime.TestExecutor$executeAndWait$2$1.invokeSuspend(TestExecutor.kt:176) at io.kotest.core.runtime.TestExecutor$executeAndWait$2$1.invoke(TestExecutor.kt) at io.kotest.core.runtime.ExecutorExecutionContext$executeWithTimeoutInterruption$$inlined$suspendCoroutine$lambda$2.invokeSuspend(ExecutorExecutionContext.kt:47) (Coroutine boundary) at io.kotest.core.runtime.TestExecutor$executeAndWait$2$1$3.invokeSuspend(TestExecutor.kt:181) at io.kotest.core.runtime.ReplayKt.replay(replay.kt:19) at io.kotest.core.runtime.TestExecutor$executeAndWait$2$1.invokeSuspend(TestExecutor.kt:180) Caused by: java.lang.IndexOutOfBoundsException: Empty list doesn't contain element at index 0. at kotlin.collections.EmptyList.get(Collections.kt:35) at kotlin.collections.EmptyList.get(Collections.kt:23) at com.papsign.ktor.openapigen.schema.builder.provider.DefaultMapSchemaProvider$Builder.build(DefaultMapSchemaProvider.kt:22) at com.papsign.ktor.openapigen.schema.builder.provider.FinalSchemaBuilderProvider$Builder.build(FinalSchemaBuilderProvider.kt:70) at com.papsign.ktor.openapigen.schema.builder.provider.DefaultObjectSchemaProvider$Builder$build$1.invoke(DefaultObjectSchemaProvider.kt:50) at com.papsign.ktor.openapigen.schema.builder.provider.DefaultObjectSchemaProvider$Builder$build$1.invoke(DefaultObjectSchemaProvider.kt:30) at com.papsign.ktor.openapigen.schema.builder.provider.DefaultObjectSchemaProvider$Builder.build(DefaultObjectSchemaProvider.kt:39) at com.papsign.ktor.openapigen.schema.builder.provider.FinalSchemaBuilderProvider$Builder.build(FinalSchemaBuilderProvider.kt:70) at com.papsign.ktor.openapigen.schema.builder.FinalSchemaBuilder$DefaultImpls.build$default(FinalSchemaBuilder.kt:8) at com.papsign.ktor.openapigen.content.type.ktor.KtorContentProvider.getMediaType(KtorContentProvider.kt:63) at com.papsign.ktor.openapigen.modules.handlers.ThrowOperationHandler.configure(ThrowOperationHandler.kt:27) at com.papsign.ktor.openapigen.modules.handlers.RouteHandler.configure(RouteHandler.kt:32) at io.github.servb.eShop.handler.product.v1.CreateProductKt.createProduct(createProduct.kt:169) at io.github.servb.eShop.route.product.v1.AddProductV1RoutesKt.addProductV1Routes(addProductV1Routes.kt:7) at io.github.servb.eShop.ApplicationKt$module$4.invoke(Application.kt:106) at io.github.servb.eShop.ApplicationKt$module$4.invoke(Application.kt) at com.papsign.ktor.openapigen.route.RouteConfigKt$apiRouting$1.invoke(RouteConfig.kt:17) at com.papsign.ktor.openapigen.route.RouteConfigKt$apiRouting$1.invoke(RouteConfig.kt) at io.ktor.routing.RoutingKt.routing(Routing.kt:120) at com.papsign.ktor.openapigen.route.RouteConfigKt.apiRouting(RouteConfig.kt:13) at io.github.servb.eShop.ApplicationKt.module(Application.kt:89) at io.github.servb.eShop.product.InMemoryEShopProductKt.inMemoryEShopProduct(inMemoryEShopProduct.kt:6) at io.github.servb.eShop.product.route.singleOperation.EShopProductCreateProductTest$1$1$1.invoke(EShopProductCreateProductTest.kt:20) at io.github.servb.eShop.product.route.singleOperation.EShopProductCreateProductTest$1$1$1.invoke(EShopProductCreateProductTest.kt:18) at io.ktor.server.testing.TestEngineKt$withTestApplication$1.invoke(TestEngine.kt:67) at io.ktor.server.testing.TestEngineKt$withTestApplication$1.invoke(TestEngine.kt) at io.ktor.server.testing.TestEngineKt.withApplication(TestEngine.kt:49) at io.ktor.server.testing.TestEngineKt.withApplication$default(TestEngine.kt:43) at io.ktor.server.testing.TestEngineKt.withTestApplication(TestEngine.kt:66) at io.github.servb.eShop.util.KotlinFutureKt.withTestApplication(KotlinFuture.kt:13) at io.github.servb.eShop.product.route.singleOperation.EShopProductCreateProductTest$1$1.invokeSuspend(EShopProductCreateProductTest.kt:20) at io.github.servb.eShop.product.route.singleOperation.EShopProductCreateProductTest$1$1.invoke(EShopProductCreateProductTest.kt) at io.kotest.core.spec.style.BehaviorSpecDsl$addGivenContext$1.invokeSuspend(behaviorSpecDsl.kt:25) at io.kotest.core.spec.style.BehaviorSpecDsl$addGivenContext$1.invoke(behaviorSpecDsl.kt) at io.kotest.core.runtime.ExecutionsKt$executeWithTimeout$2$1.invokeSuspend(executions.kt:16) at io.kotest.core.runtime.ExecutionsKt$executeWithTimeout$2$1.invoke(executions.kt) at io.kotest.core.AsserterKt.executeWithGlobalAssertSoftlyCheck(Asserter.kt:37) at io.kotest.core.runtime.ExecutionsKt$executeWithTimeout$2.invokeSuspend(executions.kt:16) at io.kotest.core.runtime.ExecutionsKt$executeWithTimeout$2.invoke(executions.kt) at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturnIgnoreTimeout(Undispatched.kt:102) at kotlinx.coroutines.TimeoutKt.setupTimeout(Timeout.kt:78) at kotlinx.coroutines.TimeoutKt.withTimeout(Timeout.kt:31) at io.kotest.core.runtime.ExecutionsKt.executeWithTimeout--MKxnPQ(executions.kt:13) at io.kotest.core.runtime.TestExecutor$executeAndWait$2$1$3.invokeSuspend(TestExecutor.kt:181) at io.kotest.core.runtime.TestExecutor$executeAndWait$2$1$3.invoke(TestExecutor.kt) at io.kotest.core.runtime.ReplayKt.replay(replay.kt:19) at io.kotest.core.runtime.TestExecutor$executeAndWait$2$1.invokeSuspend(TestExecutor.kt:176) at io.kotest.core.runtime.TestExecutor$executeAndWait$2$1.invoke(TestExecutor.kt) at io.kotest.core.runtime.ExecutorExecutionContext$executeWithTimeoutInterruption$$inlined$suspendCoroutine$lambda$2.invokeSuspend(ExecutorExecutionContext.kt:47) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:56) at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:272) at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:79) at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:54) at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source) at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:36) at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source) at io.kotest.core.runtime.ExecutorExecutionContext.executeWithTimeoutInterruption-D5N0EJY(ExecutorExecutionContext.kt:46) at io.kotest.core.runtime.TestExecutor$executeAndWait$2.invokeSuspend(TestExecutor.kt:168) at io.kotest.core.runtime.TestExecutor$executeAndWait$2.invoke(TestExecutor.kt) at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:91) at kotlinx.coroutines.CoroutineScopeKt.coroutineScope(CoroutineScope.kt:177) at io.kotest.core.runtime.TestExecutor.executeAndWait-xkB6VbI(TestExecutor.kt:165) at io.kotest.core.runtime.TestExecutor.invokeTestCase(TestExecutor.kt:149) at io.kotest.core.runtime.TestExecutor.executeActiveTest(TestExecutor.kt:116) at io.kotest.core.runtime.TestExecutor$intercept$2.invokeSuspend(TestExecutor.kt:73) at io.kotest.core.runtime.TestExecutor$intercept$2.invoke(TestExecutor.kt) at io.kotest.core.runtime.TestExecutor.executeIfActive(TestExecutor.kt:85) at io.kotest.core.runtime.TestExecutor.intercept(TestExecutor.kt:73) at io.kotest.core.runtime.TestExecutor.execute(TestExecutor.kt:54) at io.kotest.core.engine.SingleInstanceSpecRunner.runTest(SingleInstanceSpecRunner.kt:63) at io.kotest.core.engine.SingleInstanceSpecRunner$execute$2.invokeSuspend(SingleInstanceSpecRunner.kt:74) at io.kotest.core.engine.SingleInstanceSpecRunner$execute$2.invoke(SingleInstanceSpecRunner.kt) at io.kotest.core.engine.SingleInstanceSpecRunner$execute$3.invokeSuspend(SingleInstanceSpecRunner.kt:80) at io.kotest.core.engine.SingleInstanceSpecRunner$execute$3.invoke(SingleInstanceSpecRunner.kt) at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:91) at kotlinx.coroutines.CoroutineScopeKt.coroutineScope(CoroutineScope.kt:177) at io.kotest.core.engine.SingleInstanceSpecRunner.execute(SingleInstanceSpecRunner.kt:78) at io.kotest.core.engine.SpecExecutor$runTests$run$1.invokeSuspend(SpecExecutor.kt:105) at io.kotest.core.engine.SpecExecutor$runTests$run$1.invoke(SpecExecutor.kt) at io.kotest.core.engine.SpecExecutor.interceptSpec(SpecExecutor.kt:117) at io.kotest.core.engine.SpecExecutor.runTests(SpecExecutor.kt:108) at io.kotest.core.engine.SpecExecutor.execute(SpecExecutor.kt:36) at io.kotest.core.engine.KotestEngine$submitBatch$$inlined$forEach$lambda$1$1.invokeSuspend(KotestEngine.kt:78) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:56) at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:272) at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:79) at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:54) at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source) at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:36) at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source) at io.kotest.core.engine.KotestEngine$submitBatch$$inlined$forEach$lambda$1.run(KotestEngine.kt:77) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at java.base/java.lang.Thread.run(Thread.java:834) ```

Could you investigate?

SerVB commented 4 years ago

And if I change jackson to gson, I can't even run my app:

Stacktrace ``` Exception in thread "main" java.lang.reflect.InvocationTargetException at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at kotlin.reflect.jvm.internal.calls.CallerImpl$Method.callMethod(CallerImpl.kt:97) at kotlin.reflect.jvm.internal.calls.CallerImpl$Method$Static.call(CallerImpl.kt:106) at kotlin.reflect.jvm.internal.KCallableImpl.callDefaultMethod$kotlin_reflection(KCallableImpl.kt:166) at kotlin.reflect.jvm.internal.KCallableImpl.callBy(KCallableImpl.kt:110) at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.callFunctionWithInjection(ApplicationEngineEnvironmentReloading.kt:384) at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.executeModuleFunction(ApplicationEngineEnvironmentReloading.kt:330) at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.access$executeModuleFunction(ApplicationEngineEnvironmentReloading.kt:33) at io.ktor.server.engine.ApplicationEngineEnvironmentReloading$instantiateAndConfigureApplication$1$$special$$inlined$forEach$lambda$1.invoke(ApplicationEngineEnvironmentReloading.kt:275) at io.ktor.server.engine.ApplicationEngineEnvironmentReloading$instantiateAndConfigureApplication$1$$special$$inlined$forEach$lambda$1.invoke(ApplicationEngineEnvironmentReloading.kt:33) at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.avoidingDoubleStartupFor(ApplicationEngineEnvironmentReloading.kt:310) at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.access$avoidingDoubleStartupFor(ApplicationEngineEnvironmentReloading.kt:33) at io.ktor.server.engine.ApplicationEngineEnvironmentReloading$instantiateAndConfigureApplication$1.invoke(ApplicationEngineEnvironmentReloading.kt:274) at io.ktor.server.engine.ApplicationEngineEnvironmentReloading$instantiateAndConfigureApplication$1.invoke(ApplicationEngineEnvironmentReloading.kt:33) at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.avoidingDoubleStartup(ApplicationEngineEnvironmentReloading.kt:290) at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.instantiateAndConfigureApplication(ApplicationEngineEnvironmentReloading.kt:272) at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.createApplication(ApplicationEngineEnvironmentReloading.kt:125) at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.start(ApplicationEngineEnvironmentReloading.kt:245) at io.ktor.server.netty.NettyApplicationEngine.start(NettyApplicationEngine.kt:126) at io.ktor.server.netty.EngineMain.main(EngineMain.kt:26) Caused by: java.lang.IndexOutOfBoundsException: Empty list doesn't contain element at index 0. at kotlin.collections.EmptyList.get(Collections.kt:35) at kotlin.collections.EmptyList.get(Collections.kt:23) at com.papsign.ktor.openapigen.schema.builder.provider.DefaultMapSchemaProvider$Builder.build(DefaultMapSchemaProvider.kt:22) at com.papsign.ktor.openapigen.schema.builder.provider.FinalSchemaBuilderProvider$Builder.build(FinalSchemaBuilderProvider.kt:70) at com.papsign.ktor.openapigen.schema.builder.provider.DefaultObjectSchemaProvider$Builder$build$1.invoke(DefaultObjectSchemaProvider.kt:50) at com.papsign.ktor.openapigen.schema.builder.provider.DefaultObjectSchemaProvider$Builder$build$1.invoke(DefaultObjectSchemaProvider.kt:30) at com.papsign.ktor.openapigen.schema.builder.provider.DefaultObjectSchemaProvider$Builder.build(DefaultObjectSchemaProvider.kt:39) at com.papsign.ktor.openapigen.schema.builder.provider.FinalSchemaBuilderProvider$Builder.build(FinalSchemaBuilderProvider.kt:70) at com.papsign.ktor.openapigen.schema.builder.FinalSchemaBuilder$DefaultImpls.build$default(FinalSchemaBuilder.kt:8) at com.papsign.ktor.openapigen.content.type.ktor.KtorContentProvider.getMediaType(KtorContentProvider.kt:63) at com.papsign.ktor.openapigen.modules.handlers.ThrowOperationHandler.configure(ThrowOperationHandler.kt:27) at com.papsign.ktor.openapigen.modules.handlers.RouteHandler.configure(RouteHandler.kt:32) at io.github.servb.eShop.handler.product.v1.CreateProductKt.createProduct(createProduct.kt:168) at io.github.servb.eShop.route.product.v1.AddProductV1RoutesKt.addProductV1Routes(addProductV1Routes.kt:7) at io.github.servb.eShop.ApplicationKt$module$4.invoke(Application.kt:106) at io.github.servb.eShop.ApplicationKt$module$4.invoke(Application.kt) at com.papsign.ktor.openapigen.route.RouteConfigKt$apiRouting$1.invoke(RouteConfig.kt:17) at com.papsign.ktor.openapigen.route.RouteConfigKt$apiRouting$1.invoke(RouteConfig.kt) at io.ktor.routing.RoutingKt.routing(Routing.kt:120) at com.papsign.ktor.openapigen.route.RouteConfigKt.apiRouting(RouteConfig.kt:13) at io.github.servb.eShop.ApplicationKt.module(Application.kt:89) at io.github.servb.eShop.ApplicationKt.module$default(Application.kt:44) ... 23 more ```
Wicpar commented 4 years ago

The issue is that there is a map type that apparently has no map types... I didn't think this could happen...

Wicpar commented 4 years ago

can you provide sample code that does this error ?

Wicpar commented 4 years ago

Oh, Right... Do you have a class that extends the Map<K, V> Interface ?

SerVB commented 4 years ago

can you provide sample code that does this error ?

Sure.

This is the revision: https://github.com/SerVB/e-shop/tree/4db3eda7e80a3e249d2254b3bd190c3c03df3cce .

Sometimes when running ./gradlew check all tests fail (in normal case some of them pass 😀 – I'm doing TDD and haven't implemented everything yet).

If you want 100% fail (as in the second stacktrace), please apply this patch:

Index: server/src/main/kotlin/io/github/servb/eShop/Application.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- server/src/main/kotlin/io/github/servb/eShop/Application.kt (revision 4db3eda7e80a3e249d2254b3bd190c3c03df3cce)
+++ server/src/main/kotlin/io/github/servb/eShop/Application.kt (date 1585348344348)
@@ -18,7 +18,7 @@
 import io.ktor.application.call
 import io.ktor.application.install
 import io.ktor.features.ContentNegotiation
-import io.ktor.jackson.jackson
+import io.ktor.gson.gson
 import io.ktor.response.respond
 import io.ktor.response.respondRedirect
 import io.ktor.routing.get
@@ -57,7 +57,7 @@
     }

     install(ContentNegotiation) {
-        jackson()
+        gson()
     }

     install(OpenAPIGen) {
Index: server/build.gradle.kts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- server/build.gradle.kts (revision 4db3eda7e80a3e249d2254b3bd190c3c03df3cce)
+++ server/build.gradle.kts (date 1585347374395)
@@ -52,7 +52,7 @@
     implementation("io.ktor:ktor-server-netty:$ktorVersion")
     implementation("ch.qos.logback:logback-classic:$logbackVersion")
     implementation("io.ktor:ktor-server-core:$ktorVersion")
-    implementation("io.ktor:ktor-jackson:$ktorVersion")
+    implementation("io.ktor:ktor-gson:$ktorVersion")
     implementation("com.github.papsign:Ktor-OpenAPI-Generator:$ktorOpenApiGeneratorVersion")
     implementation("org.jetbrains.exposed:exposed-core:$exposedVersion")
     implementation("org.jetbrains.exposed:exposed-dao:$exposedVersion")

Then running with set env io.github.servb.eShop.forceInMemory=true ./gradlew run should fail.

Do you have a class that extends the Map<K, V> Interface ?

No...

SerVB commented 4 years ago

By the way, if I do gson { serializeNulls() }, it doesn't fail.

SerVB commented 4 years ago

The issue still blinks. I have about 50% of launches failing (do you have any idea why not always?). I've just done a small investigation: I've put a breakpoint at the failing place:

https://github.com/papsign/Ktor-OpenAPI-Generator/blob/a02ba299ee67c613847ad4529221b7a1a2fe73ad/src/main/kotlin/com/papsign/ktor/openapigen/schema/builder/provider/DefaultMapSchemaProvider.kt#L22

The problematic type is Nothing?: it doesn't have arguments:

image

I have such an object in my code:

interface OptionalResult<out ResultType : Any> {

    val data: ResultType?

    object FAIL : OptionalResult<Nothing> {

        override val data = null
    }
}

I use it as an example in throws block in some places like this:

        throws(
            status = HttpStatusCode.NotFound.description("The product does not exist."),
            example = OptionalResult.FAIL,
            exClass = IllegalArgumentException::class
        ) { ... }

Does it help?

Wicpar commented 4 years ago

That is it... it is odd that nothing is matched to a map type... I use the kotlin reflection isSubType function. Remove all the Nothings and use Unit instead, it should work.

SerVB commented 4 years ago

Oh, I think I've hacked it!

Nothing? type is a subtype of any nullable type so it's mapped to the first map entry:

https://github.com/papsign/Ktor-OpenAPI-Generator/blob/a02ba299ee67c613847ad4529221b7a1a2fe73ad/src/main/kotlin/com/papsign/ktor/openapigen/schema/builder/provider/FinalSchemaBuilderProvider.kt#L68

And tests blink because an order in the map can be random so sometimes it goes like this (which gives passing tests):

image

And sometimes like this (which gives failing tests):

image

I don't know exactly how SchemaProvider is working but it seems that there are many types defined and some strategies for them too. Maybe Nothing? can be added somewhere?

Remove all the Nothings and use Unit instead, it should work.

Sorry, I don't want to do this... For me it's very vital to have an opportunity to use OptionalResult.FAIL as all types like OptionalResult<String> or OptionalResult<MyDataClass>. If I change Nothing? to Unit?, it simply won't work because Unit isn't a subtype of any type – it's only a subtype of Any.

Wicpar commented 4 years ago

The SchemaProvider works by using a Treeset with a comparator on IsSubtype. Registering a SchemaProvider for Nothing should solve this, as it will be a subtype of everything, thus handled first.

Wicpar commented 4 years ago

I have pushed the appropriate modifications to the reworked-model branch, it should work in theory.

Wicpar commented 4 years ago

Tell me if it properly works now, i will make a pre-release and close the issue.

SerVB commented 4 years ago

It works.