ktorio / ktor

Framework for quickly creating connected applications in Kotlin with minimal effort
https://ktor.io
Apache License 2.0
12.53k stars 1.02k forks source link

Static Content(from resources) not found in Fat JAR #932

Closed MichaelFay closed 3 years ago

MichaelFay commented 5 years ago

I am trying to compile and deploy a jat jar file that contains my business logic and static content. It runs perfectly fine in intellij however, when I build a jar for deployment through graddle I get resource not found. I have already modified my statics to use resources instead of files. Any help would be greatly appreciated.

sourceSets {
    main.kotlin.srcDirs = main.java.srcDirs = ['src']
    test.kotlin.srcDirs = test.java.srcDirs = ['test']
    main.resources.srcDirs = ['resources']
    test.resources.srcDirs = ['testresources']
}

repositories {
    mavenLocal()
    jcenter()
    maven { url 'https://kotlin.bintray.com/ktor' }
}

dependencies {

    compile "khttp:khttp:0.1.0"
    compile 'io.github.rybalkinsd:kohttp:0.7.1'
    compile "com.fasterxml.jackson.module:jackson-module-kotlin:2.9.+"
    compile "com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.9.0"
    compile "io.ktor:ktor-webjars:$ktor_version"

    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.0.1"

    compile 'com.ryanharter.ktor:ktor-moshi:1.0.1'

    compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
    compile "io.ktor:ktor-server-netty:$ktor_version"
    compile "ch.qos.logback:logback-classic:$logback_version"
    compile "io.ktor:ktor-server-core:$ktor_version"
    compile "io.ktor:ktor-freemarker:$ktor_version"
    testCompile "io.ktor:ktor-server-tests:$ktor_version"
}

kotlin.experimental.coroutines = 'enable'

task fatJar(type: Jar) {
    manifest {
        attributes 'Implementation-Title': 'Gradle Jar File Example',
                'Implementation-Version': version,
                'Main-Class': 'testApplication.ApplicationKt'
    }
    baseName = project.name + '-all'
    from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
    with jar
}
fun main(args: Array<String>) {
    embeddedServer(Netty, commandLineEnvironment(args)).start()
}

//fun main(args: Array<String>): Unit = io.ktor.server.netty.EngineMain.main(args)

@kotlin.jvm.JvmOverloads
fun Application.module(testing: Boolean = false) {

    install(StatusPages){
        exception<Throwable>{

            if(it.localizedMessage != null){
                call.respondText(it.localizedMessage,
                    ContentType.Text.Plain, HttpStatusCode.InternalServerError)
            }
        }
    }

    install(ContentNegotiation){
        moshi{
            add(KotlinJsonAdapterFactory())
        }
    }

    install(FreeMarker) {
        templateLoader = ClassTemplateLoader(this::class.java.classLoader, "templates")
    }

    val db = repoMain()
    val jsonMapper = jacksonObjectMapper()

    println("starting db")
    db.update()
    println("db up")
    Timer().schedule(timerTask { db.update() }, 10000, 10000)

    routing {

        static("/static") {
            staticBasePackage  = "web"
            resources("css")
            resources("js")
        }
        get("/GetSpecificUser"){
            val user = call.request.queryParameters["user"]?.replace("+", " ")

            if(user != null){
                val dbUser = db.getSpecificUserInfo(user)

                if(dbUser != null){
                    call.respond(GetSpecificUserRequest(dbUser.userFullName,dbUser.state, dbUser.timeInState, db.getQueueData(user)))
                }
            }
        }

        get("/ReadSortQueue"){
            val reqQueue = call.request.queryParameters["name"]
            if(reqQueue != null){
                call.respond(ReadSortQueueRequest(reqQueue, db.getUserData(reqQueue)))
            }

        }

        get("/UserQueue"){
            call.respond(jsonMapper.writeValueAsString(db.getUsers().sorted()))
        }

        get("/GetQueues"){
            call.respond(jsonMapper.writeValueAsString(db.getQueues().sorted()))
        }

        get("/"){
            call.respond(
                FreeMarkerContent(
                    "index.ftl",
                    mapOf("" to "")
                )
            )
        }

        get("/allqueues"){
            call.respond(
                FreeMarkerContent(
                    "allqueues.ftl",
                    mapOf("" to "")
                )
            )
        }

        get("/index"){
            call.respondRedirect("/")
        }
    }
}

Ktor Engine Used(client or server and name)

embedded netty

JVM Version, Operating System and Relevant Context

java 1.8.191, windows 10

oleg-larshin commented 3 years ago

Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.

Stexxe commented 3 years ago

@MichaelFay I cannot reproduce your problem with Ktor 1.5.1. Here is the sample project I've created from your description fatjar_static.zip. I did the following steps:

  1. Generate fat JAR: ./gradlew fatjar
  2. Run the application: java -jar build/libs/fatjar_static-all.jar -port=9000
  3. Open http://localhost:9000/ in a browser
Bluemethyst commented 1 month ago

Hey! I've just come across this and I am having the same issue, did anyone ever find a solution?