2014-10-20 83 views
28

我已經編寫了一個簡單的kotlin源文件以便開始使用,並且還有一個gradle腳本文件。 但我不知道如何將主func添加到清單,以便該jar可以自我執行。用Gradle和Kotlin構建一個可自行執行的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") 
} 

當我啓動從終端的jar(Java的罐子MYJar.jar)我得到了下面的堆棧跟蹤,告訴我kotlin反射庫類缺失,並且確實沒有添加到jar中。似乎我錯過了最後一個罐子裏的kotlin編譯器工件類,還有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 

我使用科特林0.9.66和gradle這個2.1

+0

請注意,Kotlin爲諸如'main'等頂級函數生成的類名是在同一個文件中定義的包,以及附加了'KT'的文件名。在你的情況下,這將是'com.loloof64.kotlin.exps.MultideclarationsKT'。您可以通過在文件頂部添加'@file:JvmName(「OtherName」)'來爲文件中的所有頂級函數定義一個新的類名,從而改變這種行爲。 – 2015-12-31 00:57:42

回答

16

我已經找到了解決方法(感謝MkYong website

  1. 的gradle這個腳本需要科特林編譯神器作爲一個依賴
  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) } } 
} 
+3

對我來說它沒有編譯器的依賴關係,收集這個jar文件就足夠了 – 2015-03-16 23:56:50

+0

可以確認編譯器依賴關係是不需要的,收集文件就夠了。 – JustACluelessNewbie 2016-05-02 19:41:36

+0

執行任務後,jar在哪裏? – Franmcod 2017-11-22 12:44:15

24

添加插件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" 

事實上科特林正在建立一個類來封裝你與你的文件同名命名的主要功能 - 與標題案例。

+1

您是否可以更新您對Kotlin爲頂層功能創建類的新命名約定的回答。在他的例子中,現在是:'com.loloof64.kotlin.exps.MultideclarationsKT'作爲類名。對於Kotlin 1.0測試版和更高版本而言,情況確實如此。 – 2015-12-31 00:56:08

+0

已更新爲Kotlin 1.0 Beta及更新版本。謝謝Jayson。 – Guildenstern70 2016-01-04 15:01:32

+1

這不應該被接受的答案;它是正確的,但不是完整的圖片:它需要'收集'Kotlin運行時文件來創建一個完整的可執行文件jar,如下面的@ loloof64例子。 – 2017-04-21 02:42:06

0

如果你碰巧是愚蠢的,像我這樣的:

不要創建您的IntelliJ運行配置爲應用程序。 IntelliJ會認爲它是永不工作的Java &。相反,請使用「Kotlin」條目。

相關問題