knockmark10
knockmark10

Reputation: 113

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.

Upvotes: 6

Views: 6815

Answers (3)

knockmark10
knockmark10

Reputation: 113

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.

Upvotes: 3

Herman Sid
Herman Sid

Reputation: 71

I've faced with the same issue. My problematic configuration is:

  • Kotlin 1.5.21
  • Spring boot 2.5.2
  • Gradle 7.1.1

The problem was that in IDEA it can be run, but cannot not using gradlew command line. I went and checked all old projects. They were built and run without any problem. The difference was in versions. All my previous project had lower versions in all positions I mentioned above. So I suggested that the problem was in the version, but what tool it was? Kotlin, Spring, Gradle? I have not yet found the guilty (and no time to go into deep of this problem now), but I found a solution. If you open your jar file in any archiver (eg. WinRAR) and look at the MANIFEST.MD you will see a line starting with 'Start-Class', there is your main class and it must end with 'Kt' suffix, for example

Start-Class: me.sigest.fiveplus.FiveplusApplicationKt

In my failed jar it was not. To fix it I changed the code in build.gradle.kts file and set

springBoot {
    mainClass.set("com.example.MyMainClassKt")
}

Despite the fact that in reality my class is called MyMainClass (without suffix Kt) and it helped

P.S. all my old boot jars contain the correct name of main class with Kt. I suppose the problem is in Gradle

Upvotes: 7

Madhu A
Madhu A

Reputation: 7

Have you tried changing the main method like it is being suggested in the error message, i.e. public static void main(String[] args)

Upvotes: -3

Related Questions