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
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.