rjaros / kvision

Object oriented web framework for Kotlin/JS

Home Page:https://kvision.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Error Deploying to Heroku - no main manifest attribute, in build/libs/uat-1.0.0-SNAPSHOT.jar

chavu opened this issue · comments

I deployed successfully to Heroku yesterday. Today I deployed an update to my app and the app doesn't run. The log shows:

2023-11-21T23:16:55.149590+00:00 heroku[web.1]: Starting process with command `java -jar build/libs/uat-1.0.0-SNAPSHOT.jar`
2023-11-21T23:16:55.646280+00:00 app[web.1]: Setting JAVA_TOOL_OPTIONS defaults based on dyno size. Custom settings will override them.
2023-11-21T23:16:55.648666+00:00 app[web.1]: Picked up JAVA_TOOL_OPTIONS: -XX:+UseContainerSupport -Xmx300m -Xss512k -XX:CICompilerCount=2 -Dfile.encoding=UTF-8
2023-11-21T23:16:55.707712+00:00 app[web.1]: no main manifest attribute, in build/libs/uat-1.0.0-SNAPSHOT.jar
2023-11-21T23:16:55.787563+00:00 heroku[web.1]: Process exited with status 1
2023-11-21T23:16:55.815617+00:00 heroku[web.1]: State changed from starting to crashed

Then I added the following to gradle following advise I found on google.

    project.tasks.withType<Jar> {
        manifest {
            attributes["Main-Class"] = mainClassName
        }
    }

It's now showing the following error:

023-11-21T23:34:31.908491+00:00 heroku[web.1]: Starting process with command `java -jar build/libs/uat-1.0.0-SNAPSHOT.jar`
2023-11-21T23:34:32.566298+00:00 heroku[web.1]: Process exited with status 1
2023-11-21T23:34:32.389341+00:00 app[web.1]: Setting JAVA_TOOL_OPTIONS defaults based on dyno size. Custom settings will override them.
2023-11-21T23:34:32.391817+00:00 app[web.1]: Picked up JAVA_TOOL_OPTIONS: -XX:+UseContainerSupport -Xmx300m -Xss512k -XX:CICompilerCount=2 -Dfile.encoding=UTF-8 
2023-11-21T23:34:32.446599+00:00 app[web.1]: Error: Could not find or load main class io.ktor.server.netty.EngineMain
2023-11-21T23:34:32.446600+00:00 app[web.1]: Caused by: java.lang.ClassNotFoundException: io.ktor.server.netty.EngineMain
2023-11-21T23:34:32.587585+00:00 heroku[web.1]: State changed from starting to crashed
``

Could you post your build.gradle.kts?

Here is my full build.gradle

import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpack
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig

plugins {
    val kotlinVersion: String by System.getProperties()
    kotlin("plugin.serialization") version kotlinVersion
    kotlin("multiplatform") version kotlinVersion
    val kvisionVersion: String by System.getProperties()
    id("io.kvision") version kvisionVersion
}

version = "1.0.0-SNAPSHOT"
group = "com.digitres"

repositories {
    mavenCentral()
    mavenLocal()
}

// Versions
val kotlinVersion: String by System.getProperties()
val kvisionVersion: String by System.getProperties()
val ktorVersion: String by project
val logbackVersion: String by project
val exposedVersion: String by project

val webDir = file("src/jsMain/web")
val mainClassName = "io.ktor.server.netty.EngineMain"

kotlin {
    jvm {
        compilations.all {
            kotlinOptions {
                jvmTarget = "17"
                freeCompilerArgs = listOf("-Xjsr305=strict")
            }
        }

        @OptIn(ExperimentalKotlinGradlePluginApi::class)
        mainRun {
            mainClass.set(mainClassName)
        }

    }
    js(IR) {
        browser {
            runTask(Action {
                mainOutputFileName = "main.bundle.js"
                sourceMaps = false
                devServer = KotlinWebpackConfig.DevServer(
                    open = false,
                    port = 3000,
                    proxy = mutableMapOf(
                        "/kv/*" to "http://localhost:8080",
                        "/login" to "http://localhost:8080",
                        "/logout" to "http://localhost:8080",
                        "/kvws/*" to mapOf("target" to "ws://localhost:8080", "ws" to true)
                    ),
                    static = mutableListOf("$buildDir/processedResources/js/main")
                )
            })
            webpackTask(Action {
                mainOutputFileName = "main.bundle.js"
            })
            testTask(Action {
                useKarma {
                    useChromeHeadless()
                }
            })
        }
        binaries.executable()
    }
    sourceSets {
        val commonMain by getting {
            dependencies {
                api("io.kvision:kvision-server-ktor:$kvisionVersion")
                implementation("app.softwork:kotlinx-uuid-core:0.0.12")
                implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.3.1")
            }
            kotlin.srcDir("build/generated-src/common")
        }
        val commonTest by getting {
            dependencies {
                implementation(kotlin("test-common"))
                implementation(kotlin("test-annotations-common"))
            }
        }
        val jvmMain by getting {
            dependencies {
                implementation(kotlin("stdlib-jdk8"))
                implementation(kotlin("reflect"))
                implementation("io.ktor:ktor-server-netty:$ktorVersion")
                implementation("io.ktor:ktor-server-sessions:$ktorVersion")
                implementation("io.ktor:ktor-server-auth:$ktorVersion")
                implementation("io.ktor:ktor-server-auth-jvm:$ktorVersion")
                implementation("io.ktor:ktor-server-auth-jwt:$ktorVersion")
                implementation("io.ktor:ktor-server-compression:$ktorVersion")
                implementation("org.slf4j:slf4j-api:1.2")
                implementation("ch.qos.logback:logback-classic:$logbackVersion")
                implementation("ch.qos.logback:logback-core:$logbackVersion")
                implementation("org.jetbrains.exposed:exposed-core:$exposedVersion")
                implementation("org.jetbrains.exposed:exposed-dao:$exposedVersion")
                implementation("org.jetbrains.exposed:exposed-java-time:$exposedVersion")
                runtimeOnly("org.jetbrains.exposed:exposed-jdbc:${exposedVersion}")
                implementation("mysql:mysql-connector-java:8.0.27")
                implementation("com.zaxxer:HikariCP:5.0.1")
                implementation("org.apache.poi:poi:5.2.0")
                implementation("org.apache.poi:poi-ooxml:5.2.0")
                implementation("com.typesafe:config:1.4.1")
            }
        }
        val jvmTest by getting {
            dependencies {
                implementation(kotlin("test"))
                implementation(kotlin("test-junit"))
            }
        }
        val jsMain by getting {
            resources.srcDir(webDir)
            dependencies {
                implementation("io.kvision:kvision:$kvisionVersion")
                implementation("io.kvision:kvision-redux-kotlin:$kvisionVersion")
                implementation("io.kvision:kvision-bootstrap:$kvisionVersion")
                implementation("io.kvision:kvision-datetime:$kvisionVersion")
                implementation("io.kvision:kvision-bootstrap-upload:$kvisionVersion")
                implementation("io.kvision:kvision-fontawesome:$kvisionVersion")
                implementation("io.kvision:kvision-bootstrap-icons:$kvisionVersion")
                implementation("io.kvision:kvision-tabulator-remote:$kvisionVersion")
                implementation("io.kvision:kvision-routing-navigo:$kvisionVersion")
                implementation("io.kvision:kvision-tom-select:$kvisionVersion")
                implementation("io.kvision:kvision-state:$kvisionVersion")
                implementation("io.kvision:kvision-chart:$kvisionVersion")
                implementation("io.kvision:kvision-toastify:$kvisionVersion")
                implementation(npm("chartjs-plugin-datalabels", "2.2.0"))

            }
            kotlin.srcDir("build/generated-src/frontend")
        }
        val jsTest by getting {
            dependencies {
                implementation(kotlin("test-js"))
                implementation("io.kvision:kvision-testutils:$kvisionVersion")
            }
        }
    }

    project.tasks.named("jsProcessResources", Copy::class.java) {
        duplicatesStrategy = DuplicatesStrategy.INCLUDE
    }

    project.tasks.withType<Jar> {
        manifest {
            attributes["Main-Class"] = mainClassName
        }
    }
    project.tasks.create("stage") {
        dependsOn(project.tasks.getByName("jar"))
    }
}
//
//afterEvaluate {
//    tasks {
//        create("frontendArchive", Jar::class).apply {
//            dependsOn("frontendBrowserProductionWebpack")
//            group = "package"
//            archiveAppendix.set("frontend")
//            val distribution =
//                project.tasks.getByName("frontendBrowserProductionWebpack", KotlinWebpack::class).destinationDirectory!!
//            from(distribution) {
//                include("*.*")
//            }
//            from(webDir)
//            duplicatesStrategy = DuplicatesStrategy.EXCLUDE
//            into("/assets")
//            inputs.files(distribution, webDir)
//            outputs.file(archiveFile)
//            manifest {
//                attributes(
//                    mapOf(
//                        "Implementation-Title" to rootProject.name,
//                        "Implementation-Group" to rootProject.group,
//                        "Implementation-Version" to rootProject.version,
//                        "Timestamp" to System.currentTimeMillis()
//                    )
//                )
//            }
//        }
//        getByName("backendProcessResources", Copy::class) {
//            duplicatesStrategy = DuplicatesStrategy.EXCLUDE
//        }
//        getByName("backendJar").group = "package"
//        create("jar", Jar::class).apply {
//            dependsOn("frontendArchive", "backendJar")
//            group = "package"
//            manifest {
//                attributes(
//                    mapOf(
//                        "Implementation-Title" to rootProject.name,
//                        "Implementation-Group" to rootProject.group,
//                        "Implementation-Version" to rootProject.version,
//                        "Timestamp" to System.currentTimeMillis(),
//                        "Main-Class" to mainClassName
//                    )
//                )
//            }
//            val dependencies = configurations["backendRuntimeClasspath"].filter { it.name.endsWith(".jar") } +
//                    project.tasks["backendJar"].outputs.files +
//                    project.tasks["frontendArchive"].outputs.files
//            dependencies.forEach {
//                if (it.isDirectory) from(it) else from(zipTree(it))
//            }
//            exclude("META-INF/*.RSA", "META-INF/*.SF", "META-INF/*.DSA")
//            inputs.files(dependencies)
//            outputs.file(archiveFile)
//            duplicatesStrategy = DuplicatesStrategy.EXCLUDE
//        }
//        create("backendRun", JavaExec::class) {
//            dependsOn("compileKotlinBackend")
//            group = "run"
//            main = mainClassName
//            classpath =
//                configurations["backendRuntimeClasspath"] + project.tasks["compileKotlinBackend"].outputs.files +
//                        project.tasks["backendProcessResources"].outputs.files
//            workingDir = buildDir
//        }
//
//        create("stage") {
//            dependsOn("jar")
//        }
//    }
//}

It seems Ktor fullstack project packaging is broken in KVision 7.1.0. As a spring boot user I haven't noticed that. Sorry about this. I'll try to release a fix asap.

Thank you. I have downgraded to 7.0.1 for now and it's working okay.

Fixed in 7.2.0

I upgraded to version 7.2.0 and when I run the app in development on my laptop I 'm getting a blank white screen. See console erros in image below.

image

Any errors in the Network tab? Is your backend running? What task do you use to run the backend?

Suprising after downgrading and then upgrading again and rebuild, It's working fine now. Sorry.