Построение самопроизвольной банки с Gradle и Kotlin
Я написал простой исходный файл kotlin для начала работы и файл gradle script.
Но я не могу понять, как добавить основной функционал в манифест, чтобы банка была самоисполняемой.
Здесь мой build.gradle script:
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), я получаю следующий стек, который говорит мне, что классы библиотеки классов kotlin отсутствуют, и действительно, они не добавлены в банку. Кажется, что я пропускаю классы артефакта 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
Я использую Kotlin 0.9.66 и gradle 2.1
Ответы
Ответ 1
Я нашел обходное решение (благодаря веб-сайт MkYong)
- gradle script необходим артефакт kotlin-compiler как зависимость
- gradle script нужен способ собрать все файлы kotlin и поместить их в банку.
Итак, я получаю следующие gradle script:
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) } }
}
Ответ 2
Добавьте плагин 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 создает класс для инкапсуляции вашей основной функции с именем с тем же именем вашего файла - с заголовком.
Ответ 3
Спасибо, у меня получилось добавить раздел jar
jar {
manifest {
attributes 'Main-Class': 'com.photofiles.Application'
}
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
}
Нет необходимости в плагине приложения.
Ответ 4
В случае, если вы оказались глупыми, как я:
Не создавайте конфигурацию запуска IntelliJ как приложение. IntelliJ будет считать его Java, и он никогда не будет работать. Вместо этого используйте запись "Котлин".
Ответ 5
Если использовать Gradle
с Kotlin
DSL
, то мой дубликат вопроса имеет ответ:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
plugins {
kotlin("jvm") version "1.2.51"
id("com.github.johnrengelman.shadow") version "2.0.4"
}
group = "xxx.yyy"
version = "1.0-SNAPSHOT"
repositories {
mavenCentral()
}
dependencies {
implementation(kotlin("stdlib-jdk8"))
}
tasks.withType<KotlinCompile> {
kotlinOptions.jvmTarget = "1.8"
}
tasks.withType<ShadowJar> {
manifest.attributes.apply {
put("Implementation-Title", "Gradle Jar File Example")
//put("Implementation-Version" version)
put("Main-Class", "HelloKotlinWorld.App")
}
Что, я думаю, самое простое решение. О, возможно, вы используете только Kotlin
, а не DSL
.
Ответ 6
Ни одно из вышеупомянутых решений не помогло мне при создании Артефакта.
Версия IDE IntelliJ IDEA 2019.1.1
.
Чтобы устранить проблему, выполните следующие действия.
меры
Шаг 1 - Создание артефакта
-
Перейдите в Файл → Структура проекта → Артефакты
-
Нажмите +
→ JAR
→ From modules with dependencies
![enter image description here]()
- Выберите вашу программу
Main Class
![enter image description here]()
Шаг 2 - Изменить путь манифеста
-
Измените значение Directory for META-INF/MANIFEST.MF
на корневой каталог вашего проекта.
Например, из /your/project/directory/src/main/kotlin
в /your/project/directory
![enter image description here]()
- Нажмите
OK
, затем нажмите Apply
и OK
.
Шаг 3 - Построить артефакт
- Наконец, перейдите в
Build
→ Build Artifacts
→ [your-artifact-name]
→ Build
.
Сгенерированный файл JAR
можно найти в каталоге out/artifact/[your-artifact-name]
. (У)