tabilzad / ktor-docs-plugin

Provides Ktor Swagger support
33 stars 5 forks source link

Docker build failing - can't find openapi.yaml #32

Open knmueller opened 23 hours ago

knmueller commented 23 hours ago

Issue

(potential workaround found -- see bottom of description)

While a local build through Android Studio works correctly, running the same task in a docker build fails with:

Caused by: java.io.FileNotFoundException: /app/server/build/resources/main/openapi/openapi.yaml (No such file or directory)

Full gradle error:

 => ERROR [build 4/4] RUN ./gradlew buildFatJar --no-daemon                                                                                                                                                   55.9s
------
 > [build 4/4] RUN ./gradlew buildFatJar --no-daemon:
0.324 Downloading https://services.gradle.org/distributions/gradle-8.9-bin.zip
1.018 ............10%.............20%.............30%.............40%.............50%.............60%.............70%.............80%.............90%.............100%
9.424
9.424 Welcome to Gradle 8.9!
9.424
9.425 Here are the highlights of this release:
9.425  - Enhanced Error and Warning Messages
9.425  - IDE Integration Improvements
9.425  - Daemon JVM Information
9.425
9.426 For more details see https://docs.gradle.org/8.9/release-notes.html
9.426
9.524 To honour the JVM settings for this build a single-use Daemon process will be forked. For more on this, please refer to https://docs.gradle.org/8.9/userguide/gradle_daemon.html#sec:disabling_the_daemon in the Gradle documentation.
10.32 Daemon will be stopped at the end of the build
24.12 Type-safe project accessors is an incubating feature.
49.32 > Task :server:checkKotlinGradlePluginConfigurationErrors SKIPPED
52.32 > Task :server:processResources
54.92
54.92 > Task :server:compileKotlin
54.92 e: org.jetbrains.kotlin.util.FileAnalysisException: While analysing /app/server/src/main/kotlin/com/doctest/Application.kt:20:1: java.io.FileNotFoundException: /app/server/build/resources/main/openapi/openapi.yaml (No such file or directory)
54.92   at org.jetbrains.kotlin.util.AnalysisExceptionsKt.wrapIntoFileAnalysisExceptionIfNeeded(AnalysisExceptions.kt:57)
54.92   at org.jetbrains.kotlin.fir.FirCliExceptionHandler.handleExceptionOnFileAnalysis(Utils.kt:249)
54.92   at org.jetbrains.kotlin.fir.pipeline.AnalyseKt.runCheckers(analyse.kt:46)
54.92   at org.jetbrains.kotlin.fir.pipeline.FirUtilsKt.resolveAndCheckFir(firUtils.kt:77)
54.92   at org.jetbrains.kotlin.fir.pipeline.FirUtilsKt.buildResolveAndCheckFirViaLightTree(firUtils.kt:88)
54.92   at org.jetbrains.kotlin.cli.jvm.compiler.pipeline.JvmCompilerPipelineKt.compileModuleToAnalyzedFir(jvmCompilerPipeline.kt:319)
54.92   at org.jetbrains.kotlin.cli.jvm.compiler.pipeline.JvmCompilerPipelineKt.compileModulesUsingFrontendIrAndLightTree(jvmCompilerPipeline.kt:118)
54.92   at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:148)
54.92   at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:43)
54.92   at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:103)
54.92   at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:49)
54.92   at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:101)
54.92   at org.jetbrains.kotlin.incremental.IncrementalJvmCompilerRunner.runCompiler(IncrementalJvmCompilerRunner.kt:464)
54.92   at org.jetbrains.kotlin.incremental.IncrementalJvmCompilerRunner.runCompiler(IncrementalJvmCompilerRunner.kt:73)
54.92   at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.doCompile(IncrementalCompilerRunner.kt:506)
54.92   at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compileImpl(IncrementalCompilerRunner.kt:423)
54.92   at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compileNonIncrementally(IncrementalCompilerRunner.kt:301)
54.92   at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compile(IncrementalCompilerRunner.kt:129)
54.92   at org.jetbrains.kotlin.daemon.CompileServiceImplBase.execIncrementalCompiler(CompileServiceImpl.kt:675)
54.92   at org.jetbrains.kotlin.daemon.CompileServiceImplBase.access$execIncrementalCompiler(CompileServiceImpl.kt:92)
54.92   at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1660)
54.92   at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
54.92   at java.base/java.lang.reflect.Method.invoke(Method.java:580)
54.93   at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:360)
54.93   at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200)
54.93   at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197)
54.93   at java.base/java.security.AccessController.doPrivileged(AccessController.java:714)
54.93   at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196)
54.93   at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:598)
54.93   at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:844)
54.93   at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:721)
54.93   at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
54.93   at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:720)
54.93   at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
54.93   at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
54.93   at java.base/java.lang.Thread.run(Thread.java:1583)
54.93 Caused by: java.io.FileNotFoundException: /app/server/build/resources/main/openapi/openapi.yaml (No such file or directory)
54.93   at java.base/java.io.FileOutputStream.open0(Native Method)
54.93   at java.base/java.io.FileOutputStream.open(FileOutputStream.java:289)
54.93   at java.base/java.io.FileOutputStream.<init>(FileOutputStream.java:230)
54.93   at java.base/java.io.FileOutputStream.<init>(FileOutputStream.java:179)
54.93   at kotlin.io.FilesKt__FileReadWriteKt.writeText(FileReadWrite.kt:141)
54.93   at kotlin.io.FilesKt__FileReadWriteKt.writeText$default(FileReadWrite.kt:140)
54.93   at io.github.tabilzad.ktor.FileUtilsKt.serializeAndWriteTo(FileUtils.kt:33)
54.93   at io.github.tabilzad.ktor.k2.SwaggerDeclarationChecker.check(SwaggerDeclarationChecker.kt:62)
54.93   at io.github.tabilzad.ktor.k2.SwaggerDeclarationChecker.check(SwaggerDeclarationChecker.kt:25)
54.93   at org.jetbrains.kotlin.fir.analysis.collectors.components.DeclarationCheckersDiagnosticComponent.check(DeclarationCheckersDiagnosticComponent.kt:133)
54.93   at org.jetbrains.kotlin.fir.analysis.collectors.components.DeclarationCheckersDiagnosticComponent.visitSimpleFunction(DeclarationCheckersDiagnosticComponent.kt:61)
54.93   at org.jetbrains.kotlin.fir.analysis.collectors.components.DeclarationCheckersDiagnosticComponent.visitSimpleFunction(DeclarationCheckersDiagnosticComponent.kt:19)
54.93   at org.jetbrains.kotlin.fir.declarations.FirSimpleFunction.accept(FirSimpleFunction.kt:51)
54.93   at org.jetbrains.kotlin.fir.analysis.collectors.CheckerRunningDiagnosticCollectorVisitor.checkElement(CheckerRunningDiagnosticCollectorVisitor.kt:24)
54.93   at org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollectorVisitor.access$checkElement(AbstractDiagnosticCollectorVisitor.kt:30)
54.93   at org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollectorVisitor.visitWithDeclarationAndReceiver(AbstractDiagnosticCollectorVisitor.kt:1376)
54.93   at org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollectorVisitor.visitSimpleFunction(AbstractDiagnosticCollectorVisitor.kt:118)
54.93   at org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollectorVisitor.visitSimpleFunction(AbstractDiagnosticCollectorVisitor.kt:30)
54.93   at org.jetbrains.kotlin.fir.declarations.FirSimpleFunction.accept(FirSimpleFunction.kt:51)
54.93   at org.jetbrains.kotlin.fir.declarations.impl.FirFileImpl.acceptChildren(FirFileImpl.kt:57)
54.93   at org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollectorVisitor.visitNestedElements(AbstractDiagnosticCollectorVisitor.kt:38)
54.93   at org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollectorVisitor.visitFile(AbstractDiagnosticCollectorVisitor.kt:1151)
54.93   at org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollectorVisitor.visitFile(AbstractDiagnosticCollectorVisitor.kt:30)
54.93   at org.jetbrains.kotlin.fir.declarations.FirFile.accept(FirFile.kt:42)
54.93   at org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollector.collectDiagnostics(AbstractDiagnosticCollector.kt:36)
54.93   at org.jetbrains.kotlin.fir.pipeline.AnalyseKt.runCheckers(analyse.kt:34)
54.93   ... 33 more
54.93
55.02
55.02 > Task :server:compileKotlin FAILED
55.02
55.02 FAILURE: Build failed with an exception.
55.02
55.02 * What went wrong:
55.02 Execution failed for task ':server:compileKotlin'.
55.02 > A failure occurred while executing org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction
55.02    > Internal compiler error. See log for more details
55.02
...

Stack

Windows 10 w/ Android Studio Ladybug 2024.2.1 Kotlin multiplatform with only Ktor (kotlin 2.0.21, ktor 3.0.0) - also tried with ktor 2.3.12 ktor-docs-plugin version 0.6.4-alpha

Example repo

I generated a simple KMP project with the multiplatform generator, and added the appropriate annotations: https://github.com/knmueller/DocTestProject

You can find the Dockerfile in docker/Dockerfile

Reproduction

To repro the issue, run

docker build --pull -f docker/Dockerfile -t server .

The build fails at step RUN ./gradlew buildFatJar --no-daemon

Note

I also tried using :server:build and then buildFatJar as gradle tasks in the Dockerfile, but it fails with the same error as above on the :server:build task.

If I had to guess, there seems to be some issue with order of generating the openapi yaml in a kotlin multiplatform project.

Workaround

Note -- I believe I just found a workaround by adding an empty openapi.yaml file in server/src/resources/openapi/openapi.yaml. The plugin appears to overwrite the file when adding it to the final jar. See workaround branch in the example repository

tabilzad commented 15 hours ago

Thanks for reporting, I believe this has to do with gradle config caching. Should be patched in 0.6.5