Использование Gradle для создания jar с зависимостями
У меня есть мультипроектная сборка, и я поставил задачу построить жирную банку в одном из подпроектов. Я создал задачу, похожую на ту описано в кулинарной книги.
jar {
from configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
manifest { attributes 'Main-Class': 'com.benmccann.gradle.test.WebServer' }
}
запуск его приводит к следующей ошибке:
Причина: Вы не можете изменить конфигурация, которая не находится в неразрешенное состояние!
Я не уверен, что эта ошибка означает. я также сообщил об этом на Gradle JIRA в случае, если это ошибка.
8 ответов:
Я написал решение в JIRA против Gradle:
// Include dependent libraries in archive. mainClassName = "com.company.application.Main" jar { manifest { attributes "Main-Class": "$mainClassName" } from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } }
если вы хотите
jar
задача вести себя нормально и интереснойfatJar
задач, использовать следующее:task fatJar(type: Jar) { classifier = 'all' from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } with jar }
и
with jar
. Без него классы этого проекта не включаются.
ответ @felix почти привел меня туда. У меня было два вопроса:
- С Gradle 1.5 тег манифеста не был распознан внутри задачи fatJar, поэтому атрибут основного класса не мог быть установлен напрямую
- у jar были конфликтующие внешние файлы META-INF.
следующая настройка разрешает это
jar { manifest { attributes( 'Main-Class': 'my.project.main', ) } } task fatJar(type: Jar) { manifest.from jar.manifest classifier = 'all' from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } { exclude "META-INF/*.SF" exclude "META-INF/*.DSA" exclude "META-INF/*.RSA" } with jar }
чтобы добавить это в стандартную задачу сборки или сборки, добавьте:
artifacts { archives fatJar }
редактировать: спасибо @mjaggard: в последних версиях Gradle, change
configurations.runtime
доconfigurations.runtimeClasspath
это прекрасно работает для меня.
мой основной класс:
package com.curso.online.gradle; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; public class Main { public static void main(String[] args) { Logger logger = Logger.getLogger(Main.class); logger.debug("Starting demo"); String s = "Some Value"; if (!StringUtils.isEmpty(s)) { System.out.println("Welcome "); } logger.debug("End of demo"); } }
и это содержимое моего файла сборки.Gradle в:
apply plugin: 'java' apply plugin: 'eclipse' repositories { mavenCentral() } dependencies { compile group: 'commons-collections', name: 'commons-collections', version: '3.2' testCompile group: 'junit', name: 'junit', version: '4.+' compile 'org.apache.commons:commons-lang3:3.0' compile 'log4j:log4j:1.2.16' } task fatJar(type: Jar) { manifest { attributes 'Main-Class': 'com.curso.online.gradle.Main' } baseName = project.name + '-all' from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } with jar }
и я пишу следующее в консоли:
java -jar ProyectoEclipseTest-all.jar
а это:
log4j:WARN No appenders could be found for logger (com.curso.online.gradle.Main) . log4j:WARN Please initialize the log4j system properly. log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more in fo. Welcome
чтобы создать жирную банку с основным исполняемым классом, избегая проблем с подписанными банками, я предлагаю gradle-One-jar плагин. Простой плагин, который использует проект One-JAR.
простота в использовании:
apply plugin: 'gradle-one-jar' buildscript { repositories { mavenCentral() } dependencies { classpath 'com.github.rholder:gradle-one-jar:1.0.4' } } task myjar(type: OneJar) { mainClass = 'com.benmccann.gradle.test.WebServer' }
простое решение
jar { manifest { attributes 'Main-Class': 'cova2.Main' } doFirst { from { configurations.runtime.collect { it.isDirectory() ? it : zipTree(it) } } } }
ответ от @ben почти работает для меня, за исключением того, что мои зависимости слишком велики, и я получил следующую ошибку
Execution failed for task ':jar'. > archive contains more than 65535 entries. To build this archive, please enable the zip64 extension.
исправить эту проблему, я должен использовать следующий код
mainClassName = "com.company.application.Main" jar { manifest { attributes "Main-Class": "$mainClassName" } zip64 = true from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } }