Ответ 1
Найден решение на форуме Gradle:
jar {
manifest {
attributes(
"Class-Path": configurations.compile.collect { it.getName() }.join(' '))
}
}
Источник: Манифест с помощью класса Path в Jar Task для подпроектов
Я бы хотел, чтобы мой Gradle build script добавлял полный путь к файлу манифеста, содержащийся в файле JAR, созданном после сборки.
Пример:
Manifest-Version: 1.0
Class-Path: MyProject.jar SomeLibrary.jar AnotherLib.jar
Моя сборка script уже добавляет в манифест некоторую информацию:
jar {
manifest {
attributes("Implementation-Title": project.name,
"Implementation-Version": version,
"Main-Class": mainClassName,
}
}
Как мне получить список зависимостей для добавления в манифест?
Эта страница обучающих программ Java описывает более подробно, как и почему добавление пути к манифесту: Добавление классов в путь к файлу класса JAR
Найден решение на форуме Gradle:
jar {
manifest {
attributes(
"Class-Path": configurations.compile.collect { it.getName() }.join(' '))
}
}
Источник: Манифест с помощью класса Path в Jar Task для подпроектов
В последних версиях Gradle compile
и runtime
устарели. Вместо этого используйте runtimeClasspath
следующим образом:
'Class-Path': configurations.runtimeClasspath.files.collect { it.getName() }.join(' ')
Обратите внимание, что если вы используете Kotlin DSL, вы можете настроить манифест следующим образом:
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"
}
}
Поместите это в конец файла buid.gradle
. Измените com.example.Main
на собственный основной класс.
jar {
doFirst {
manifest {
if (!configurations.compile.isEmpty()) {
attributes(
'Class-Path': configurations.compile.collect{it.toURI().toString()}.join(' '),
'Main-Class': 'com.example.Main')
}
}
}
}
Верхние ответы ей очень помогли мне. Вот что сработало для меня:
jar {
manifest {
attributes "Main-Class": "your.package.classWithMain"
attributes "Class-Path": configurations.compile.collect { it.absolutePath }.join(" ")
}
}
Итак, вместо имени мне пришлось использовать absolutePath. Это может работать или не работать для вас. Некоторые предлагают использовать время выполнения вместо компиляции. Я использовал компиляцию, потому что у меня есть раздел компиляции в зависимостях в моей build.gradle. Итак, шаг в jar забирает зависимости оттуда. Лучше всего подобрать то, что, по вашему мнению, будет работать, сделать конструкцию gradle, затем найти файл JAR и развернуть его, чтобы найти файл META-INF/MANIFEST.MF. Вы должны уметь видеть все каталоги, разделенные пробелами. Если нет, вы должны попробовать что-то другое. Функция автозаполнения вашей среды IDE должна быть полезной при просмотре того, какие все методы или поля доступны в конфигурациях/компиляции и т.д. Все это можно легко сделать в IntelliJ.
Oh.., и если вы хотите увидеть, где библиотеки JAR физически расположены на вашем диске, щелкните правой кнопкой мыши на своем проекте- > параметры открытого модуля- > Библиотеки, а затем щелкните любую библиотеку.
Я знаю, что это, вероятно, тривиально для людей groovy здесь, но в моем случае я хотел изменить расположение Class-Path
в файле манифеста в зависимости от того, будет ли я запускаться в рабочей среде или местной среде. Я сделал это, создав раздел build.gradle
jar следующим образом:
jar {
from configurations.runtime
manifest {
attributes ('Main-Class': 'com.me.Main',
'Class-Path': configurations.runtime.files.collect { jarDir+"/$it.name" }.join(' ')
)
}
}
В этом случае аргумент gradle build
передается так:
$ gradle build -PjarDir="/opt/silly/path/"
У меня была аналогичная, но не идентичная проблема. Я публиковал свой lib jar L в artifactory и позже извлекал его как зависимость от модуля M, но переходные зависимости, которые L для компиляции и времени выполнения, не поступали с ним. Мне потребовалось некоторое время, чтобы понять, что моя банка была опубликована в artifactory с пустым файлом pom, поэтому gradle не смог узнать, какие L-транзитивные зависимости будут выбраны. Пропущенный кусок был инструкцией в L build.gradle, чтобы опубликовать pom. Как часто с gradle, связь между именем insturction и его значением полностью:
apply plugin: 'maven'
uploadArchives {
repositories {
mavenDeployer {
repository(url: "file://localhost/tmp/myRepo/")
}
}
}
Источник: uploading_to_maven_repositories