如何使用Ktor Kotlin / Java应用程序中的gradle构建有效的JAR文件

我一直在试图为我的Kotlin / Java Ktor项目创建一个可执行的JAR。 用我的gradle脚本创建实际的JAR很简单,但无论如何,我不能为我的生活弄清楚如何通过错误消息:“JAR文件:无法find主类路由。主键”。 我的Kotlin主函数位于包路由中名为Main.kt的文件中。 下面是我的gradle文件。 我究竟做错了什么?

buildscript { ext.kotlin_version = '1.2.21' ext.ktorVersion = '0.9.0' repositories { mavenCentral() } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } apply plugin: 'java' apply plugin: 'kotlin' sourceCompatibility = 1.8 compileKotlin { kotlinOptions.jvmTarget = "1.8" } compileTestKotlin { kotlinOptions.jvmTarget = "1.8" } kotlin { experimental { coroutines "enable" } } jar { manifest { attributes 'Main-Class': "routing.MainKt" } from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } } repositories { mavenCentral() jcenter() maven { url "https://dl.bintray.com/kotlin/kotlinx" } maven { url "https://dl.bintray.com/kotlin/ktor" } maven { url "http://repository.jetbrains.com/kotlin-nosql" } maven { url "https://oss.sonatype.org/content/repositories/snapshots" } } dependencies { //Core Ktor libs compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8" compile "io.ktor:ktor-server-core:$ktorVersion" compile "io.ktor:ktor-server-netty:$ktorVersion" compile "io.ktor:ktor-freemarker:$ktorVersion" compile "io.ktor:ktor-locations:$ktorVersion" ...Other libs } 

编辑:当我在生成的jar上运行jar tf我得到以下相关的信息:

 routing/MainKt$chartsxyzApplication$5.class routing/MainKt$chartsxyzApplication$5$1.class routing/MainKt$chartsxyzApplication$4.class routing/MainKt$chartsxyzApplication$4$1.class routing/MainKt.class routing/MainKt$redirect$1.class routing/MainKt$chartsxyzApplication$5$2.class routing/MainKt$chartsxyzApplication$2.class routing/MainKt$chartsxyzApplication$1.class routing/MainKt$chartsxyzApplication$3.class routing/MainKt$main$1.class 

Edit2:这是Main.kt的基础知识

 package routing import io.ktor.application.* ... @location("/") class Index ... A bunch of other locations fun main(args: Array) { embeddedServer(Netty, 8080, module = Application::chartsApplication).start() } fun Application.chartsApplication(){ ... } suspend fun ApplicationCall.redirect(location: Any) { ... } fun ApplicationCall.refererHost() = request.header(HttpHeaders.Referrer)?.let { URI.create(it).host } 

我认为简单的方法是使用shadowjar插件

它将把你所有的库包含到你的jar中。

这里有一个使用Gradle Kotlin DSL的例子:

https://github.com/s1monw1/ktor_application/blob/master/build.gradle.kts

 application { applicationName = "ktorapp" group = "whatever" mainClassName = "your main" } tasks { withType { manifest { attributes(mapOf("Main-Class" to application.mainClassName)) } val version = "1.0-SNAPSHOT" archiveName = "${application.applicationName}-$version.jar" from(configurations.compile.map { if (it.isDirectory) it else zipTree(it) }) } } 

这是使用shadowjar插件的替代方法。

task fatJar(type: Jar) { manifest { attributes 'Implementation-Title': project.name, 'Implementation-Version': version, 'Main-Class': 'class.path.to.MainKt' } baseName = project.name from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } exclude 'META-INF/*.RSA', 'META-INF/*.SF', 'META-INF/*.DSA' with jar }