web-dev-qa-db-fra.com

Ajouter un chemin de classe dans manifeste à l'aide de Gradle

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

40
Paolo Fulgoni

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

65
Paolo Fulgoni

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(' ')

MODIFIER:

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"
    }
}
14
Eng.Fouad

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')
            }
        }
    }
}
6
fssilva

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.

4
Vikas

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/"
2
Sonny

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

0
kumetix