Подтвердить что ты не робот

Построение самопроизвольной банки с 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

4b9b3361

Ответ 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 - Создание артефакта

  1. Перейдите в Файл → Структура проекта → Артефакты

  2. Нажмите +JARFrom modules with dependencies

enter image description here

  1. Выберите вашу программу Main Class

enter image description here

Шаг 2 - Изменить путь манифеста

  1. Измените значение Directory for META-INF/MANIFEST.MF на корневой каталог вашего проекта.

    Например, из /your/project/directory/src/main/kotlin в /your/project/directory

enter image description here

  1. Нажмите OK, затем нажмите Apply и OK.

Шаг 3 - Построить артефакт

  1. Наконец, перейдите в BuildBuild Artifacts[your-artifact-name]Build.

Сгенерированный файл JAR можно найти в каталоге out/artifact/[your-artifact-name]. (У)