Создание uberjar с помощью Gradle

Я хочу создать uberjar (также известный как Fatjar), который включает в себя все транзитивные зависимости проекта. Какие строки мне нужно добавить в build.gradle?

Это то, что у меня есть на данный момент:

task uberjar(type: Jar) {
    from files(sourceSets.main.output.classesDir)

    manifest {
        attributes 'Implementation-Title': 'Foobar',
                'Implementation-Version': version,
                'Built-By': System.getProperty('user.name'),
                'Built-Date': new Date(),
                'Built-JDK': System.getProperty('java.version'),
                'Main-Class': mainClassName
    }
}

person missingfaktor    schedule 11.06.2012    source источник
comment
Вместо этого вы можете попробовать использовать плагин приложения.   -  person Scott    schedule 05.02.2014
comment
Это будет работать до тех пор, пока у вас нет никаких зависимостей. Но как только в вашем проекте появятся зависимости, они не будут включены в uberjar.   -  person Stefan Neuhaus    schedule 16.03.2017


Ответы (4)


Вы пробовали пример Fatjar в поваренной книге Gradle?

Вам нужен теневой плагин для gradle.

person tim_yates    schedule 11.06.2012
comment
Спасибо за указатель. Это помогло. Хотя я столкнулся с другой проблемой, которая была решена путем поиска в Google. Я добавлю еще один ответ, расширяющий это. - person missingfaktor; 12.06.2012
comment
Похоже, что кулинарная книга теперь требует авторизации. Поскольку это именно то, что я ищу, не могли бы вы вставить рецепт сюда, пожалуйста? - person oarsome; 07.04.2015
comment
@tarzan три года спустя, и теперь я буду использовать теневой плагин github.com/johnrengelman/shadow - person tim_yates; 07.04.2015
comment
это очень просто и сработало в первый раз (попробовав множество других ответов: stackoverflow.com/questions/23738676/ - person Hugo Zaragoza; 30.04.2015
comment
Все меняется за 3 года. И я бы все равно использовал теневой плагин ;-) - person tim_yates; 30.04.2015
comment
shadowjar не очень хорошо поддерживается. См. github.com/johnrengelman/shadow/issues/476 и другие важные проблемы, которые пропал без вести в течение нескольких месяцев. - person Gili; 27.06.2019

Я заменил task uberjar(.. на следующее:

jar {
    from(configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }) {
        exclude "META-INF/*.SF"
        exclude "META-INF/*.DSA"
        exclude "META-INF/*.RSA"
    }

    manifest {
        attributes 'Implementation-Title': 'Foobar',
                'Implementation-Version': version,
                'Built-By': System.getProperty('user.name'),
                'Built-Date': new Date(),
                'Built-JDK': System.getProperty('java.version'),
                'Main-Class': mainClassName
    }
}

Исключения необходимы, потому что в их отсутствие вы столкнетесь с этой проблемой.

person missingfaktor    schedule 11.06.2012
comment
Я думаю, что он должен использовать configurations.runtime для включения всех зависимостей времени выполнения. - person lyomi; 12.09.2014
comment
мне нужно было добавить with jar ниже манифеста, чтобы получить файлы в java/main/resources в uberjar - person gladiator; 30.12.2014
comment
Это сработало для меня! Без части исключения это убивало меня SecurityException, и с этим исправлением это работает! - person techcraver; 02.04.2018
comment
Лучше даже использовать sourceSets.getByName('main').runtimeClasspath - person mkobit; 31.07.2018
comment
кто-нибудь знает, как это будет выглядеть в kotlin (для файла build.gradle,kts)? - person user64141; 17.12.2019

Просто добавьте это в build.gradle вашего java-модуля.

mainClassName = "мой.основной.Класс"

jar {
  manifest { 
    attributes "Main-Class": "$mainClassName"
  }  

  from {
    configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
  }
}

Это приведет к созданию файла [имя_модуля]/build/libs/[имя_модуля].jar.

person Bao Le    schedule 26.11.2016
comment
но что это за код? Что делает configurations.compile.collect { it.isDirectory() ? это : zipTree(это) } сделать? - person Sam Redway; 21.04.2017
comment
@SamRedway configurations.compile.collect собирает данные из compile Тернар позволяет извлекать как папки, так и zip-файлы (например, jar), как если бы они также были папками. - person pal; 03.07.2017
comment
Я не пробовал другие версии, размещенные здесь, но эта работает хорошо, красиво и просто. - person chris; 18.07.2017
comment
Этот ответ исключает любые объявленные зависимости runtime или runtimeOnly, которые могут привести к сбою приложения во время выполнения. - person mkobit; 31.07.2018
comment
@mkobit Вы можете заменить compile на runtimeClasspath, как указано в этот ответ. - person Franklin Yu; 01.03.2019

Я нашел этот проект очень полезным. Используя его в качестве ссылки, моя задача Gradle uberjar будет

task uberjar(type: Jar, dependsOn: [':compileJava', ':processResources']) {
    from files(sourceSets.main.output.classesDir)
    from configurations.runtime.asFileTree.files.collect { zipTree(it) }

    manifest {
        attributes 'Main-Class': 'SomeClass'
    }
}
person boechat107    schedule 24.09.2014
comment
я получаю Invalid signature file digest for Manifest main attributes, когда пробую это - person Nicholas DiPiazza; 31.08.2017
comment
вам нужно exclude "META-INF/*.SF" exclude "META-INF/*.DSA" exclude "META-INF/*.RSA" как ответ Missingfaktor - person Nicholas DiPiazza; 31.08.2017
comment
Похоже, не работает с Gradle 5.3.1: не удалось получить неизвестное свойство classesDir для основных классов типа org.gradle.api.internal.tasks.DefaultSourceSetOutput. - person lathspell; 06.04.2019
comment
это дает мне java.lang.UnsupportedOperationException - person aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; 19.03.2020