Création D'un pot exécutable avec Gradle

Jusqu'à présent, j'ai créé des fichiers JAR exécutables via L'exportation Eclipse"..."functionallity mais maintenant je suis passé à IntelliJ IDEA et Grad pour l'automatisation de construction.

certains articles ici suggèrent le plugin" application", mais cela ne conduit pas entièrement au résultat auquel je m'attendais (juste un bocal, pas de scripts de démarrage ou quelque chose comme ça).

Comment puis-je obtenir le même résultat Qu'Eclipse fait avec l ' "exportation... boîte de dialogue"?

99
demandé sur Roland 2014-02-12 11:15:44

8 réponses

un fichier JAR exécutable est juste un fichier jar contenant une entrée de classe principale dans son manifeste. Il vous suffit donc de configurer la tâche jar pour ajouter cette entrée dans son manifeste:

jar {
    manifest {
        attributes 'Main-Class': 'com.foo.bar.MainClass'
    }
}

vous pourriez aussi avoir besoin d'ajouter des entrées classpath dans le manifeste, mais cela serait fait de la même manière.

voir http://docs.oracle.com/javase/tutorial/deployment/jar/manifestindex.html

110
répondu JB Nizet 2014-02-12 07:26:16

les réponses de JB Nizet et Jorge_B sont correctes.

dans sa forme la plus simple, créer un JAR exécutable avec Gradle est juste une question d'ajouter les entrées appropriées au manifeste . Cependant, il est beaucoup plus courant d'avoir des dépendances qui doivent être incluses sur le chemin de classe, ce qui rend cette approche difficile dans la pratique.

le application plugin fournit une approche alternative; à la place de la création d'un JAR exécutable, il fournit:

  • a run tâche pour faciliter l'exécution facile de l'application directement à partir de la construction
  • une tâche installDist qui génère une structure de répertoire comprenant le JAR construit, tous les JARs dont il dépend, et un script de démarrage qui le tire tous ensemble dans un programme que vous pouvez exécuter""
  • distZip et distTar tâches créer des archives contenant un application complète de la distribution (les scripts de démarrage et Bocaux)

une troisième approche consiste à créer un "fat JAR" qui est un JAR exécutable qui inclut non seulement le code de votre composant, mais aussi toutes ses dépendances. Il ya quelques différents plugins qui utilisent cette approche. J'ai inclus des liens vers quelques-uns que je connais; je suis sûr qu'il y en a d'autres.

74
répondu davidmc24 2017-10-18 08:16:05

comme d'autres l'ont fait remarquer, pour qu'un fichier jar soit exécutable, le point d'entrée de la demande doit être défini dans l'attribut Main-Class du fichier manifeste. Si les fichiers de la classe de dépendances ne sont pas co-localisés, alors ils doivent être définis dans l'entrée Class-Path du fichier manifest.

j'ai essayé toutes sortes de combinaisons de plugin et ce n'est pas pour la tâche simple de créer un pot exécutable et d'une façon ou d'une autre, inclure les dépendances. Tous les plugins semblent manquent d'une manière ou d'une autre, mais enfin je l'ai eu comme je le voulais. Pas de scripts mystérieux, pas un million de mini-fichiers différents polluant le répertoire de compilation, un fichier de script de compilation assez propre, et surtout pas un million de fichiers de classe de tiers étrangers fusionnés dans mon archive jar.

ce qui suit est un copier-coller de ici pour votre commodité..

[comment] créer un fichier zip de distribution avec les barres de dépendances dans le sous-répertoire /lib et ajouter toutes les dépendances à Class-Path entrée dans le fichier manifeste:

  apply plugin: 'java'
apply plugin: 'java-library-distribution'

repositories {
    mavenCentral()
}

dependencies {
    compile 'org.apache.commons:commons-lang3:3.3.2'
}

// Task "distZip" added by plugin "java-library-distribution":
distZip.shouldRunAfter(build)

jar {
    // Keep jar clean:
    exclude 'META-INF/*.SF', 'META-INF/*.DSA', 'META-INF/*.RSA', 'META-INF/*.MF'

    manifest {
        attributes 'Main-Class': 'com.somepackage.MainClass',
                   'Class-Path': configurations.runtime.files.collect { "lib/$it.name" }.join(' ')
    }
    // How-to add class path:
    //     /q/add-classpath-in-manifest-using-gradle-42785/"https://gist.github.com/MartinanderssonDotcom/c63675ce87947da1ef4a" rel="noreferrer">here.

The result can be found in build/distributions et le contenu Non zippé ressemblent à ceci:

lib / commons-lang3-3.3.2.jar

MyJarFile.jar

contenu de MyJarFile.jar#META-INF/MANIFEST.mf :

Manifeste-Version: 1.0

Principal-Classe: com.somepackage.Classe principale

Class-Path: lib / commons-lang3-3.3.2.jar



29
répondu Martin Andersson 2017-05-23 12:10:41

la solution la moins d'effort pour moi était de faire usage du Grad-shadow-plugin

en plus d'appliquer le plugin tout ce qui doit être fait est:

  • configurer la tâche jar pour mettre votre classe principale dans le manifeste

    pot { manifester { les attributs Principaux de la Classe': 'com.mon.app." } }

  • exécuter le gradle tâche ./ gradlew shadowJar

  • prendre le app-Version-tous.jar à partir de build/libs/

et enfin l'exécuter via:

java -jar app-version-all.jar
17
répondu Ostkontentitan 2015-09-09 07:38:18

avez-vous essayé la tâche "installApp"? N'est-il pas de créer un répertoire complet avec un ensemble de scripts de démarrage?

http://www.gradle.org/docs/current/userguide/application_plugin.html

5
répondu Jorge_B 2014-02-12 07:18:46

vous pouvez définir un artéfact jar dans les paramètres du module (ou la structure du projet).

  • clic droit sur le module > ouvrir les paramètres du module > artéfacts > + > JAR > à partir de modules avec dépendances.
  • définit la classe principale.

fabriquer un bocal est alors aussi facile que de cliquer sur" Construire un artefact..."dans le menu générer. En prime, vous pouvez empaqueter toutes les dépendances dans un seul bocal.

Testé sur IntelliJ IDEA 14 Ultimate.

3
répondu Mondain 2015-02-08 13:04:53

Merci Konstantin, ça a fonctionné comme un charme avec peu de nuances. Pour une certaine raison, spécifier la classe principale comme partie de jar manifest ne fonctionnait pas tout à fait et il voulait l'attribut mainClassName à la place. Voici un extrait de construire.gradle qui comprend tout pour le faire fonctionner:

plugins {
  id 'java' 
  id 'com.github.johnrengelman.shadow' version '1.2.2'
}
...
...
apply plugin: 'application'
apply plugin: 'com.github.johnrengelman.shadow'
...
...
mainClassName = 'com.acme.myapp.MyClassMain'
...
...
...
shadowJar {
    baseName = 'myapp'
}

après avoir exécuté gradle shadowJar vous obtenez myapp - {version} - tout.jar dans votre dossier de construction qui peut être exécuté comme java-jar myapp - {version} - all.pot.

3
répondu Alex Yavorskiy 2015-12-06 19:40:10

j'ai vérifié plusieurs liens pour la solution, j'ai finalement fait les étapes mentionnées ci-dessous pour la faire fonctionner. Je suis à l'aide de Gradle 2.9.

apporter les modifications suivantes à votre fichier build, gradle:

  1. de Mentionner plugin:

    apply plugin: 'eu.appsatori.fatjar'
    
  2. Fournir à l'Buildscript:

    buildscript {
    repositories {
        jcenter()
    }
    
    dependencies {
        classpath "eu.appsatori:gradle-fatjar-plugin:0.3"
    }
    }
    
  3. indiquer la classe principale:

    fatJar {
      classifier 'fat'
      manifest {
        attributes 'Main-Class': 'my.project.core.MyMainClass'
      }
      exclude 'META-INF/*.DSA', 'META-INF/*.RSA', 'META-INF/*.SF'
    }
    
  4. Créer le fatjar:

    ./gradlew clean fatjar
    
  5. Exécuter le fatjar de /build/libs/ :

    java -jar MyFatJar.jar
    
2
répondu Sandeep Sarkar 2016-02-03 23:22:02