Вопрос:

Использование Gradle для создания JAR с зависимостями

gradle uberjar

115303 просмотра

8 ответа

10286 Репутация автора

У меня есть мультипроектная сборка, и я поставил задачу создать толстый флягу в одном из подпроектов. Я создал задачу, аналогичную той, которая описана в кулинарной книге .

jar {
  from configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
  manifest { attributes 'Main-Class': 'com.benmccann.gradle.test.WebServer' }
}

Запуск его приводит к следующей ошибке:

Причина: Вы не можете изменить конфигурацию, которая не находится в неразрешенном состоянии!

Я не уверен, что означает эта ошибка. Я также сообщил об этом на Gradle JIRA в случае, если это ошибка .

Автор: Ben McCann Источник Размещён: 02.02.2011 07:09

Ответы (8)


157 плюса

10286 Репутация автора

Решение

Я опубликовал решение в 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) }
  }
}

Обратите внимание, что mainClassNameдолжно появиться ДО jar {.

Автор: Ben McCann Размещён: 04.02.2011 03:34

60 плюса

3480 Репутация автора

Если вы хотите, чтобы jarзадача работала нормально и выполнялась дополнительно fatJar, используйте следующее:

task fatJar(type: Jar) {
    classifier = 'all'
    from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
    with jar
}

Важной частью является with jar. Без этого классы этого проекта не включены.

Автор: Felix Размещён: 25.03.2014 04:33

8 плюса

747 Репутация автора

Это прекрасно работает для меня.

Мой основной класс:

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");
    }

}

И это содержимое моего файла build.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
Автор: Aron Elias Herrera Ponte Размещён: 10.08.2014 07:42

2 плюса

28 Репутация автора

Простое решение

jar {
    manifest {
        attributes 'Main-Class': 'cova2.Main'
    } 
    doFirst {
        from { configurations.runtime.collect { it.isDirectory() ? it : zipTree(it) } }
    }
}
Автор: Jonas Mayer Размещён: 09.02.2015 09:26

-1 плюса

31 Репутация автора

Если вы привыкли к муравью, вы можете попробовать то же самое с Gradle:

task bundlemyjava{
    ant.jar(destfile: "build/cookmyjar.jar"){
        fileset(dir:"path to your source", includes:'**/*.class,*.class', excludes:'if any')
        } 
}
Автор: mig Размещён: 28.04.2015 12:58

51 плюса

869 Репутация автора

Ответ @felix почти привел меня туда. У меня было две проблемы:

  1. В Gradle 1.5 тег манифеста не распознавался внутри задачи fatJar, поэтому атрибут Main-Class не мог быть установлен напрямую
  2. в банке были конфликтующие внешние файлы 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 измените configurations.runtimeнаconfigurations.runtimeClasspath

Автор: blootsvoets Размещён: 15.07.2015 09:22

5 плюса

9427 Репутация автора

Чтобы сгенерировать толстый JAR с основным исполняемым классом, избегая проблем с подписанными JAR, я предлагаю плагин 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'
}
Автор: Italo Borssatto Размещён: 29.10.2015 05:08

3 плюса

31 Репутация автора

Ответ от @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) }
  }
}
Автор: Algorithm Размещён: 15.03.2018 10:45
Вопросы из категории :
32x32