Search code examples
spring-bootkotlingradleheroku

Spring Boot + Kotlin + Gradle - Error: Main method not found in class


I'm learning spring boot with Kotlin (since I come from Android with Kotlin). I set it up with gradle. In my local machine everything works just fine. But I'm having a few issues while trying to deploy it to Heroku.

This is the error I'm getting:

Error: Main method not found in class com.markoid.packit.PackitApplication, please define the main method as:
2021-07-01T20:58:51.075484+00:00 app[web.1]:    public static void main(String[] args)
2021-07-01T20:58:51.075581+00:00 app[web.1]: or a JavaFX application class must extend javafx.application.Application

I read on other posts that I need to add system.properties file in the root, so I did, but nothing changes.

system.properties

java.runtime.version=11

And this is my build.gradle.kts

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    id("org.springframework.boot") version "2.5.1"
    id("io.spring.dependency-management") version "1.0.11.RELEASE"
    kotlin("jvm") version "1.5.10"
    kotlin("plugin.spring") version "1.5.10"
}

group = "com.markoid"
version = "1.0.0-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_11

repositories {
    mavenCentral()
}

dependencies {
    // Spring Boot Core
    implementation("org.springframework.boot:spring-boot-starter-web")
    implementation("org.springframework.boot:spring-boot-starter-validation")
    implementation("org.springframework.boot:spring-boot-starter-security")
    implementation("org.springframework.boot:spring-boot-starter-mail")
    implementation("org.springframework.boot:spring-boot-starter-data-mongodb")

    // Joda Time library
    implementation("joda-time:joda-time:2.10")

    // Json Web Token
    implementation("io.jsonwebtoken:jjwt-impl:0.11.1")
    implementation("io.jsonwebtoken:jjwt-api:0.11.1")
    implementation("io.jsonwebtoken:jjwt-jackson:0.11.1")

    // Serializers
    implementation("com.fasterxml.jackson.module:jackson-module-kotlin")

    // Documentation
    implementation("io.springfox:springfox-swagger2:2.6.1")

    // Kotlin related
    implementation("org.jetbrains.kotlin:kotlin-reflect")
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

    // Testing Frameworks
    testImplementation("org.springframework.boot:spring-boot-starter-test")
}

tasks.withType<KotlinCompile> {
    kotlinOptions {
        freeCompilerArgs = listOf("-Xjsr305=strict")
        jvmTarget = "11"
    }
}

tasks.withType<Test> {
    useJUnitPlatform()
}

tasks.withType<Jar> {
    manifest {
        attributes["Main-Class"] = "com.markoid.packit.PackitApplication"
    }
}

My app file is as simple as this:

@SpringBootApplication
class PackitApplication

fun main(args: Array<String>) {
    runApplication<PackitApplication>(*args)
}

Does someone know what I'm missing? This is the first project on spring I'm trying to deploy on heroku, so please bare with me.

Thank you in advance.


Solution

  • I just had to a few things to make it work:

    1. In the build.gradle.kts, I removed the tasks with type jar, and added this:
    springBoot {     
        mainClass.set("com.markoid.packit.PackitApplicationKt")
    }
    
    1. I needed to add a Procfile, with the following:

      web: java -Dserver.port=$PORT $JAVA_OPTS -jar build/libs/packit-1.0.0-SNAPSHOT.jar

    Such file will tell heroku the specific command I want to be executed to run the generated jar.