Reputation: 1113
I tried to copy the Spring Boot Kotlin sample project https://github.com/JetBrains/kotlin-examples/tree/master/tutorials/spring-boot-restful. I Added some more dependencies and when I tried to build the executable jar and run it, I got the error:
Could not find or load main class...
Gradle build script:
buildscript {
ext.kotlin_version = '1.1.3' // Required for Kotlin integration
ext.spring_boot_version = '1.5.4.RELEASE'
repositories {
jcenter()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // Required for Kotlin integration
classpath "org.jetbrains.kotlin:kotlin-allopen:$kotlin_version" // See https://kotlinlang.org/docs/reference/compiler-plugins.html#kotlin-spring-compiler-plugin
classpath "org.springframework.boot:spring-boot-gradle-plugin:$spring_boot_version"
}
}
/*plugins {
id 'org.springframework.boot' version '2.0.0.RELEASE'
}*/
apply plugin: 'kotlin' // Required for Kotlin integration
apply plugin: "kotlin-spring" // See https://kotlinlang.org/docs/reference/compiler-plugins.html#kotlin-spring-compiler-plugin
apply plugin: 'org.springframework.boot'
jar {
baseName = 'gs-rest-service'
version = '0.1.0'
from {
(configurations.runtime).collect {
it.isDirectory() ? it : zipTree(it)
}
}
manifest {
attributes 'Main-Class': 'org.jetbrains.kotlin.demo.Applicationkt'
}
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin/'
test.java.srcDirs += 'src/test/kotlin/'
}
repositories {
jcenter()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" // Required for Kotlin integration
compile("org.springframework.boot:spring-boot-starter-web")
compile group: 'org.apache.camel', name: 'camel-quartz2', version: '2.20.2'
compile group: 'org.apache.camel', name: 'camel-http4', version: '2.20.2'
compile group: 'org.apache.camel', name: 'camel-docker', version: '2.20.2'
compile group: 'org.apache.camel', name: 'camel-aws', version: '2.20.2'
testCompile('org.springframework.boot:spring-boot-starter-test')
}
Upvotes: 8
Views: 20963
Reputation: 504
One small (but easily overlooked) thing: Your Application.kt file has a class Application inside which the main function is present.
For example:
class Application {
fun main(args: Array<String>): Unit {
// your logic
}
}
Instead, your main function should be out of the class:
fun main(args: Array<String>) {
// your logic
}
And now in your build.gradle.kts
file:
application {
mainClass.set("<package>.ApplicationKt")
}
should work
Upvotes: 0
Reputation: 4058
For me the main function needed to be outside the class body
@SpringBootApplication
@Configuration
class Application
(private val locationRepository: LocationRepository,
) : CommandLineRunner {
override fun run(vararg args: String?) {
whatever()
}
}
fun main(args: Array<String>) {
runApplication<Application>(*args)
}
Upvotes: 1
Reputation: 22292
Indeed, Kotlin create file ApplicationKt.class
in the jar if your main class file is named Application.kt
. You have to add the following lines:
apply plugin: 'kotlin'
apply plugin: 'application'
mainClassName = 'org.jetbrains.kotlin.demo.ApplicationKt'
If you use the classic jar
plugin, you can do as below (which is described in previous responses):
jar {
manifest {
attributes 'Main-Class': 'org.jetbrains.kotlin.demo.ApplicationKt'
}
from {
configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
}
}
However, my preference is to use bootJar
plugin which is much clear and which allow me to use layered jars for example:
bootJar {
layered() // Not useful if you don't want to use layered jars
}
Upvotes: 0
Reputation: 6569
Change Applicationkt
to ApplicationKt
will work, and BTW you may upgrade Kotlin version to 1.3.50
.
By Applicationkt
I mean the one in this line:
attributes 'Main-Class': 'org.jetbrains.kotlin.demo.Applicationkt'
Upvotes: 7
Reputation: 531
Kotlin compiles the Application file in two different files:
In this second file is where the main function is located at, so you have to use this name in the build.gradle file.
mainClassName = 'org.jetbrains.kotlin.demo.ApplicationKt'
Upvotes: 6
Reputation: 4731
Update your build.gradle to
jar {
manifest {
attributes 'Main-Class': 'org.jetbrains.kotlin.demo.ApplicationKt'
}
from {
configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
}
}
with an upper case K in ApplicationKt.
This is required because of the way Kotlin compiles to Java Bytecode. The fun main()
function in Kotlin is not attached to any class, but Java always requires a class and does not support classless functions.
The Kotlin compiler has to create a Java class. Because you already defined a class Application
it created one with the suffix Kt
for the functions in your Kotlin file org/jetbrains/kotlin/demo/Application.kt
. You have to set this class so that the JVM can find it.
BTW a Jar file is just a Zip file, you can unpack it and see for yourself if the ApplicationKt.class is there.
Upvotes: 2