Een zelfuitvoerbare pot bouwen met Gradle en Kotlin

Ik heb een eenvoudig kotlin-bronbestand geschreven om te beginnen, en een gradle-scriptbestand.
Maar ik weet niet hoe ik de hoofdfunctie aan het manifest kan toevoegen, zodat de jar zelfuitvoerbaar kan zijn.

Hier mijn 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'
    }
}

Hier is mijn 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")
}

Als ik de jar start vanuit terminal (java -jar MYJar.jar) krijg ik de volgende stacktrace, die me zegt dat de kotlin-reflectiebibliotheekklassen ontbreken en dat ze inderdaad niet aan de jar zijn toegevoegd. Het lijkt erop dat ik de kotlin-compiler-artefactklassen uit de laatste pot mis, en ook de kotlin-stdlib-bronnen, maar ik weet niet hoe ik de gradle-build moet aanpassen.

$> 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

Ik gebruik Kotlin 0.9.66 en gradle 2.1


Antwoord 1, autoriteit 100%

Voeg de plug-in applicationtoe en stel vervolgens de mainClassNamein als

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

Stel bijvoorbeeld dat je de volgende code in een bestand met de naam main.kthebt geplaatst:

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

uw build.gradlemoet zijn:

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

In feite bouwt Kotlineen klasse om uw hoofdfunctie met dezelfde naam als uw bestand in te kapselen – met Titel Case.


Antwoord 2, autoriteit 73%

Ik heb de oplossing gevonden (dankzij MkYong-website)

  1. Het gradle-script had het kotlin-compiler-artefact nodig als afhankelijkheid
  2. Het gradle-script had een manier nodig om alle kotlin-bestanden te verzamelen en in de pot te stoppen.

Dus ik krijg het volgende 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) } }
}

Antwoord 3, autoriteit 41%

Geen van de bovenstaande oplossingen werkte voor mij tijdens het bouwen van Artifact.

IDE versie IntelliJ IDEA 2019.1.1.

Doe het volgende om het probleem op te lossen

Stappen

Stap 1 – Artefact maken

  1. Ga naar Bestand -> Projectstructuur -> Artefacten

  2. Klik op de +-> JAR-> From modules with dependencies

voer hier de afbeeldingsbeschrijving in

  1. Selecteer de Main Class
  2. van uw programma

voer hier de afbeeldingsbeschrijving in

Stap 2 – MANIFEST-pad wijzigen

  1. Wijzig de waarde van Directory for META-INF/MANIFEST.MFin de hoofdmap van uw project.

    Bijvoorbeeld , van /your/project/directory/src/main/kotlinnaar /your/project/directory

voer hier de afbeeldingsbeschrijving in

  1. Druk op OKen vervolgens op Applyen OK.

Stap 3 – Bouw artefact

  1. Ga ten slotte naar Build-> Build Artifacts-> [your-artifact-name]-> Build.

Het gegenereerde JAR-bestand is te vinden in de directory out/artifact/[your-artifact-name]. (j)


Antwoord 4, autoriteit 5%

Bedankt, voor mij werkte het om de jar-sectie toe te voegen

jar {
    manifest {
        attributes 'Main-Class': 'com.photofiles.Application'
    }
    from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
}

De applicatie-plug-in is niet nodig.


Antwoord 5, autoriteit 3%

Voor het geval je dom bent, zoals ik:

Maak uw IntelliJ-runconfiguratie niet aan als een toepassing. IntelliJ gaat ervan uit dat het Java & het zal nooit werken. Gebruik in plaats daarvan de invoer “Kotlin”.


Antwoord 6, autoriteit 3%

Als u Gradlegebruikt met de KotlinDSL, dan is mijn dubbelevraag heeft een antwoord van:

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")
    }

Dat is, denk ik, de eenvoudigste oplossing. Oh, misschien gebruik je alleen Kotlinzelf en niet de DSL.


Antwoord 7

Voor iedereen die de Kotlin MP-plug-in gebruikt, is hier uw code

jvm{
    jvmJar {
        manifest{
            attributes 'Main-Class':'Class path here'
        }
    }
}

Other episodes