Использование Gradle для создания jar с зависимостями
У меня есть сборка мультипроекта, и я поставил задачу построить жирную банку в одном из подпроектов. Я создал задачу, похожую на one описано в кулинарной книги.
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 почти привел меня туда. У меня было два вопроса:--5-->
- С Gradle 1.5 тег манифеста не был распознан внутри задачи fatJar, поэтому атрибут Main-Class не мог быть установлен напрямую
- у 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
}
Edit: благодаря @mjaggard: в последних версиях Gradle, change configurations.runtime
to 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'
}
простой sulution
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) }
}
}
Если вы привыкли к ant, то вы можете попробовать то же самое с Gradle тоже:
task bundlemyjava{
ant.jar(destfile: "build/cookmyjar.jar"){
fileset(dir:"path to your source", includes:'**/*.class,*.class', excludes:'if any')
}
}