Hello everyone, I am trying to build a ktor multi ...
# community-support
p
Hello everyone, I am trying to build a ktor multi module project for the first time.(trying to use convention plugin) I was able to create pure kotlin and other(database(exposed)) subprojects but unable to build a ktor project. I read the docs and studied some books (Gradle in Action) but don't really know how to do. Could you guys took into it and give some suggestion. I am sharing some part of the project and also sharing the git repo and a diagram of what i am trying to achieve on the thread.
settings.gradle.kts (Root)
Copy code
pluginManagement {
    includeBuild("build-logic")

    repositories {
        gradlePluginPortal()
        mavenCentral()
        maven { url = uri("<https://packages.confluent.io/maven/>") }
    }
}


rootProject.name = "kyoku-server"
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")

include("core:domain")
findProject(":core:domain")?.name = "domain"
include("core:database")
findProject(":core:database")?.name = "database"
include("core:data")
findProject(":core:data")?.name = "data"

include("user:data")
findProject(":user:data")?.name = "data"
include("user:domain")
findProject(":user:domain")?.name = "domain"
build.gradle.kts (Root)
Copy code
plugins {
    alias(libs.plugins.kotlin.jvm) apply false
    alias(libs.plugins.ktor) apply false
    alias(libs.plugins.kotlinx.serialization) apply false
}

group = "com.poulastaa.kyoku"
version = "1.0"
build-logic settings.gradle.kts (build-logic)
Copy code
dependencyResolutionManagement {
    repositories {
        mavenCentral()
    }

    versionCatalogs {
        create("libs") {
            from(files("../gradle/libs.versions.toml"))
        }
    }
}

rootProject.name = "build-logic"
include(":convention")
build.gradle.kts (build-logic:convention)
Copy code
plugins {
    `kotlin-dsl`
}

repositories {
    gradlePluginPortal()
    mavenCentral()
}

group = "com.poulastaa.kyoku.buildlogic"

dependencies {
    compileOnly(libs.kotlin.gradlePlugin)
}

gradlePlugin {
    plugins {
        register("jvmLibrary") {
            id = "kyoku.jvm.library"
            implementationClass = "JVMLibraryConventionPlugin"
        }

        register("ktorApplication") {
            id = "kyoku.ktor.application"
            implementationClass = "KtorConventionPlugin"
        }


        register("ktorExposed") {
            id = "kyoku.ktor.exposed"
            implementationClass = "ExposedConventionPlugin"
        }

        register("ktorKoin") {
            id = "kyoku.ktor.koin"
            implementationClass = "KoinConventionPlugin"
        }
    }
}
JVMLibraryConventionPlugin
Copy code
import com.poulastaa.convention.configureKotlinJvm
import com.poulastaa.convention.libs
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.dependencies
import org.gradle.kotlin.dsl.repositories

class JVMLibraryConventionPlugin : Plugin<Project> {
    override fun apply(target: Project) {
        target.run {
            pluginManager.apply("org.jetbrains.kotlin.jvm")
            configureKotlinJvm()

            repositories {
                mavenCentral()
            }

            group = "com.poulastaa.kyoku"
            version = "1.0"

            dependencies {
                "implementation"(libs.findBundle("kotlin").get())
            }
        }
    }
}
KtorConventionPlugin
Copy code
import com.poulastaa.convention.libs
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.plugins.JavaApplication
import org.gradle.kotlin.dsl.dependencies

class KtorConventionPlugin : Plugin<Project> {
    override fun apply(target: Project) {
        target.run {
            pluginManager.run {
                apply("kyoku.jvm.library")

                apply("io.ktor.plugin")
                apply("org.jetbrains.kotlin.plugin.serialization")
            }

            dependencies {
                "implementation"(libs.findBundle("ktor").get())
                "testImplementation"(libs.findBundle("ktor-test").get())
            }

            extensions.configure(JavaApplication::class.java) {
                mainClass.set("io.ktor.server.netty.EngineMain")

                val isDevelopment: Boolean = project.hasProperty("development")
                applicationDefaultJvmArgs = listOf("-Dio.ktor.development=$isDevelopment")
            }
        }
    }
}
build.gradle.kts (userdata)
Copy code
plugins {
    alias(libs.plugins.kyoku.jvm.library)
}


dependencies {
    implementation(project(":core:domain"))
    implementation(project(":user:domain"))
}
Kyoku Multi Module Idea.svg
v
Two things spring to mind from a coarse look. Why do you set the projects' names to their default value in the settings script? And having mutliple projects with the same and very minimal name is seldomly a good idea. Latest when you package it together you will have mutliple files called
domain-1.0.0.jar
and besides that it is unclear what it it is, you probably will end up with only one of them or an error. Besides these things, you did not mention what problem you actually have.
p
Thanks for responding. I fixed the project names
Copy code
include("core:domain")
findProject(":core:domain")?.name = "core-domain"
include("core:database")
findProject(":core:database")?.name = "core-database"
include("core:data")
findProject(":core:data")?.name = "core-data"

include("user:data")
findProject(":user:data")?.name = "user-data"
include("user:domain")
findProject(":user:domain")?.name = "user-domain"
When i was trying to build the ktor project,getting error
duplicate dependency
but i am not able to recreate the error. This is the ktor project build.gradle.kts file
Copy code
plugins {
    alias(libs.plugins.kyoku.ktor.application)
}

dependencies {
    implementation(project(":core:core-domain"))
    implementation(project(":auth:auth-domain"))
    implementation(project(":details:details-domain"))
    implementation(project(":play:play-domain"))
    implementation(project(":search:search-domain"))
    implementation(project(":suggestion:suggestion-domain"))
    implementation(project(":user:user-domain"))
}
maybe Changing the project names fixed the error.
v
Yes, most probably, that's what I said, you will end up with some jars missing, or error messages, so error messages it was 🙂
Though I would use the actual project name in the
include
and then set the project directory instead of the name. 🙂 Just a style difference, but seems cleaner to me. And I would also use
project(...)
not
findProject(...)
the projects should be there, if not that is most probably a typo and should bring up an error imho.
p
'I would use the actual project name in the
include
and then set the project directory instead of the name' Yes i am doing it now. previous solution is temporary one to see if i am making some other mistakes. 'I would also use
project(...)
not `findProject(...)`' ok I will change it.
👌 1