用Gradle和Kotlin构建一个可执行的jar

我已经写了一个简单的kotlin源文件,以便开始,并且一个gradle脚本文件。 但我不知道如何将主要的func添加到清单,以便该jar可以自我执行。

这里我的build.gradle脚本:

buildscript { repositories { mavenCentral() } dependencies { classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:0.9.66' } } apply plugin: "kotlin" repositories { mavenCentral() } dependencies { compile 'org.jetbrains.kotlin:kotlin-stdlib:0.9.66' } jar { manifest { attributes 'Main-Class': 'com.loloof64.kotlin.exps.ExpsPackage' } } 

这是我的com.loloof64.kotlin.exps.Multideclarations.kt

 package com.loloof64.kotlin.exps class Person(val firstName: String, val lastName: String) { fun component1(): String { return firstName } fun component2(): String { return lastName } } fun main(args: Array < String > ) { val(first, last) = Person("Laurent", "Bernabé") println("First name : $first - Last name : $last") } 

当我从终端(java -jar MYJar.jar)启动jar时,我得到了下面的堆栈跟踪,说kotlin反射库类丢失了,实际上它们没有被添加到jar中。 看来我错过了最后一个jar文件中的kotlin-compiler工件类,还有kotlin-stdlib源文件,但是我不知道如何调整gradle的构建。

 $> java -jar build/libs/kotlin_exps.jar Exception in thread "main" java.lang.NoClassDefFoundError: kotlin/reflect/jvm/internal/InternalPackage at com.loloof64.kotlin.exps.ExpsPackage.<clinit>(MultiDeclarations.kt) Caused by: java.lang.ClassNotFoundException: kotlin.reflect.jvm.internal.InternalPackage at java.net.URLClassLoader$1.run(URLClassLoader.java:372) at java.net.URLClassLoader$1.run(URLClassLoader.java:361) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:360) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ... 1 more 

我正在使用Kotlin 0.9.66和gradle 2.1

添加插件application ,然后将mainClassName设置为

 mainClassName = '[your_namespace].[your_arctifact]Kt' 

例如,假设您将以下代码放在名为main.kt的文件中:

 package net.mydomain.kotlinlearn import kotlin import java.util.ArrayList fun main(args: Array<String>) { println("Hello!") } 

你的build.gradle应该是:

 apply plugin: 'kotlin' apply plugin: 'application' mainClassName = "net.mydomain.kotlinlearn.MainKt" 

事实上, Kotlin正在建立一个类来封装你的名字为你的文件的主要函数 – Title Case。

我找到了解决办法(感谢MkYong网站 )

  1. gradle脚本需要kotlin编译器工件作为依赖
  2. gradle脚本需要一种方法来收集所有的kotlin文件并将它们放入jar中。

所以我得到了以下的Gradle脚本:

 buildscript { repositories { mavenCentral() } dependencies { classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.0.1-2' } } apply plugin: "kotlin" repositories { mavenCentral() } dependencies { compile 'org.jetbrains.kotlin:kotlin-stdlib:1.0.1-2' } jar { manifest { attributes 'Main-Class': 'com.loloof64.kotlin.exps.MultideclarationsKT' } // NEW LINE HERE !!! from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } } 

如果你碰巧是愚蠢的,像我一样:

不要将IntelliJ运行配置创建为应用程序。 IntelliJ会认为它是Java的,它将永远不会工作。 而是使用“Kotlin”条目。