Dockerfile can not build jar file : Main class name has not been configured

Viewed 706

I am building a dockerfile for a microservices architecture (spring) but I find some difficulties. I got this error when buidling the boot jar

Main class name has not been configured and it could not be resolved

my dockerfile is

FROM gradle:6.5-jdk11 AS TEMP_BUILD_IMAGE
ENV APP_HOME=/usr/app/
WORKDIR $APP_HOME
COPY build.gradle.kts settings.gradle.kts $APP_HOME

COPY gradle $APP_HOME/gradle
COPY --chown=gradle:gradle . /home/gradle/src
USER root
RUN chown -R gradle /home/gradle/src

RUN gradle bootJar || return 0
COPY . .
RUN gradle clean bootJar 

FROM openjdk:11-jdk
ENV ARTIFACT_NAME=app.jar
ENV APP_HOME=/usr/app/

WORKDIR $APP_HOME
COPY --from=TEMP_BUILD_IMAGE $APP_HOME/build/libs/$ARTIFACT_NAME .

ENTRYPOINT exec java -jar ${ARTIFACT_NAME}

The error is in 9th step

RUN gradle bootJar || return 0

I tried to put the name of the class in the gradle file, and i got this error

Exception in thread "main" java.lang.NoSuchMethodException: com.test.config.ConfigServerApp.main([Ljava.lang.String;)

this is my gradle file

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.springframework.boot.gradle.tasks.bundling.BootJar

plugins {
    id("io.spring.dependency-management") version "1.0.9.RELEASE"
    id("org.springframework.boot") version "2.3.0.RELEASE"
    kotlin("plugin.spring") version "1.3.72"
    kotlin("jvm") version "1.3.72"
}

repositories {
    mavenCentral()
}

group = "com.test"
version = "1.0.0"
java.sourceCompatibility = JavaVersion.VERSION_11

extra["springCloudVersion"] = "Hoxton.SR5"

dependencies {
    implementation("org.jetbrains.kotlin:kotlin-reflect")
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

    implementation("org.springframework.cloud:spring-cloud-config-server")
    implementation("org.springframework.cloud:spring-cloud-config-monitor")
    implementation("org.springframework.cloud:spring-cloud-starter-bus-amqp")

    testImplementation("org.springframework.boot:spring-boot-starter-test") {
        exclude(group = "org.junit.vintage", module = "junit-vintage-engine")
    }
}

dependencyManagement {
    imports {
        mavenBom("org.springframework.cloud:spring-cloud-dependencies:${property("springCloudVersion")}")
    }
}

tasks.withType<Test> {
    useJUnitPlatform()
}

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

tasks.withType<BootJar> {
    archiveFileName.set("app.jar")
    mainClassName = "com.test.config.ConfigServerApp"
}

this is my main class (i m using kotlin)

package com.test.config

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.cloud.config.server.EnableConfigServer

@EnableConfigServer
@SpringBootApplication
class ConfigServerApp

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

when I launch the application from my editor it works, but when I launch it from the jar file or from docker, it does not work

how can i fix this please?

2 Answers

Just to make a formal answer from my comment since it worked. As I explained in the comment: When we use Kotlin, the real main class is generated behind the scenes with Kt suffix, you should find it in your build folder after running gradle bootJar.

You should update the mainClassName to com.test.config.ConfigServerAppKt as shown below:

tasks.withType<BootJar> {
    archiveFileName.set("app.jar")
    mainClassName = "com.test.config.ConfigServerAppKt"
}

As explained in the Kotlin docs :

All the functions and properties declared in a file app.kt inside a package org.example, including extension functions, are compiled into static methods of a Java class named org.example.AppKt.

So your main method will be part of java class named ConfigServerAppKt after compilation. So you should change your mainClassName to com.test.config.ConfigServerAppKt.

Related