J'aimerais que mon script de génération Gradle ajoute le chemin d'accès complet au fichier manifeste contenu dans le fichier JAR créé après la génération.
Exemple:
Manifest-Version: 1.0
Class-Path: MyProject.jar SomeLibrary.jar AnotherLib.jar
Mon script de construction ajoute déjà quelques informations au manifeste de cette façon:
jar {
manifest {
attributes("Implementation-Title": project.name,
"Implementation-Version": version,
"Main-Class": mainClassName,
}
}
Comment puis-je obtenir la liste des dépendances à ajouter au manifeste?
Cette page de Java décrit plus en détail comment et pourquoi ajouter un chemin de classe au manifeste: Ajout de classes au chemin de classe du fichier JAR
Trouver une solution sur le forum de Gradle:
jar {
manifest {
attributes(
"Class-Path": configurations.compile.collect { it.getName() }.join(' '))
}
}
Source: Manifeste avec tâche Classpath in Jar pour les sous-projets
Dans les dernières versions de gradle, compile
et runtime
deviennent obsolètes. À la place, utilisez runtimeClasspath
comme suit:
'Class-Path': configurations.runtimeClasspath.files.collect { it.getName() }.join(' ')
Notez que si vous utilisez Kotlin DSL, vous pouvez configurer le manifeste comme suit:
configure<JavaPluginConvention> { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 manifest { attributes( "Manifest-Version" to "1.0", "Main-Class" to "io.fouad.AppLauncher") } }
tasks.withType(Jar::class) {
manifest {
attributes["Manifest-Version"] = "1.0"
attributes["Main-Class"] = "io.fouad.AppLauncher"
}
}
Placez ceci à la fin du buid.gradle
fichier. Changer la com.example.Main
à votre propre classe principale.
jar {
doFirst {
manifest {
if (!configurations.compile.isEmpty()) {
attributes(
'Class-Path': configurations.compile.collect{it.toURI().toString()}.join(' '),
'Main-Class': 'com.example.Main')
}
}
}
}
Les réponses les plus importantes m'ont beaucoup aidée. Voici ce qui a fonctionné pour moi:
jar {
manifest {
attributes "Main-Class": "your.package.classWithMain"
attributes "Class-Path": configurations.compile.collect { it.absolutePath }.join(" ")
}
}
Donc, au lieu de nommer, je devais utiliser absolutePath. Cela peut ou peut ne pas fonctionner pour vous. Certains suggèrent d'utiliser runtime au lieu de compiler. J'ai utilisé compiler parce que j'ai une section de compilation dans les dépendances de mon build.gradle. Ainsi, l’étape jar récupère les dépendances à partir de là. La meilleure chose à faire est de choisir quelque chose qui, à votre avis, fonctionnera, de construire un dégradé, puis de trouver le fichier JAR et de le développer pour trouver le fichier META-INF/MANIFEST.MF. Vous devriez pouvoir voir tous les répertoires séparés par des espaces. Sinon, vous devriez essayer quelque chose de différent. La fonctionnalité de saisie semi-automatique de votre IDE devrait être utile pour déterminer toutes les méthodes ou tous les champs disponibles dans les configurations/compiler, etc. Tout cela peut être fait facilement dans IntelliJ.
Oh .. et si vous voulez voir où se trouvent physiquement les JAR de la bibliothèque sur votre disque, cliquez avec le bouton droit de la souris sur votre projet-> ouvrir les paramètres du module-> Bibliothèques, puis cliquez sur n’importe quelle bibliothèque.
Je sais que ceci est probablement trivial pour les personnes qui ont du succès ici, mais dans mon cas, je voulais changer l'emplacement du Class-Path
Dans le fichier manifeste en fonction de mon exécution dans l'environnement de production ou dans l'environnement local. . Je l'ai fait en donnant à ma section jar build.gradle
:
jar {
from configurations.runtime
manifest {
attributes ('Main-Class': 'com.me.Main',
'Class-Path': configurations.runtime.files.collect { jarDir+"/$it.name" }.join(' ')
)
}
}
Dans ce cas, l'argument de gradle build
Est passé comme suit:
$ gradle build -PjarDir="/opt/silly/path/"
J'ai eu un problème similaire mais pas identique. Je publiais mon lib jar L dans l'artéfact, puis je le récupérais en tant que dépendance du module M, mais les dépendances transitives, celles dont L avait besoin pour la compilation et l'exécution, ne lui étaient pas parvenues. Il m'a fallu un certain temps pour comprendre que mon pot était publié dans l'artefact avec un fichier pom vide, donc Gradle n'était pas en mesure de savoir quelles dépendances transitives de L devaient être extraites. La pièce manquante était une instruction, dans le build.gradle du L, de publier le pom. Comme souvent avec gradle, le lien entre le nom de l’instruction et sa signification est complètement:
apply plugin: 'maven'
uploadArchives {
repositories {
mavenDeployer {
repository(url: "file://localhost/tmp/myRepo/")
}
}
}
Source: ploading_to_maven_repositories