2011-02-02 112 views
88

我有一個多項目構建,並且我把一個任務放在一個子項目中構建一個胖罐子。我創建了類似於described in the cookbook的任務。使用Gradle構建一個具有依賴關係的罐子

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

運行它導致以下錯誤:

Cause: You can't change a configuration which is not in unresolved state!

我不知道這是什麼錯誤表示。 I also reported this on the Gradle JIRA in case it is a bug

回答

133

我在JIRA發佈a solution對搖籃:

// 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) } 
    } 
} 
+3

我不得不修改這configurations.runtime.collect爲我的項目,我有運行時依賴以及。 – vextorspace 2016-06-29 17:32:33

+0

我不得不添加`def mainClassName`來使代碼工作......我收到了無法爲根項目設置未知屬性'mainClassName' – hanskoff 2017-05-12 12:45:08

+1

如何處理文件名衝突?不同JAR中相同路徑上的文件將被覆蓋。 – waste 2017-08-20 10:47:39

52

如果你想jar任務正常行爲和additinal fatJar任務,使用以下命令:

task fatJar(type: Jar) { 
    baseName = project.name + '-all' 
    from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } 
    with jar 
} 

的重要組成部分,是with jar 。沒有它,這個項目的類不包括在內。

6

這對我來說很好。

我的主類:

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 
2

簡單sulution

jar { 
    manifest { 
     attributes 'Main-Class': 'cova2.Main' 
    } 
    doFirst { 
     from { configurations.runtime.collect { it.isDirectory() ? it : zipTree(it) } } 
    } 
} 
-1

如果你已經習慣了螞蟻,那麼你可以嘗試用搖籃也一樣:

task bundlemyjava{ 
    ant.jar(destfile: "build/cookmyjar.jar"){ 
     fileset(dir:"path to your source", includes:'**/*.class,*.class', excludes:'if any') 
     } 
} 
37

通過@felix答案几乎把我帶到那裏。我有兩個問題:

  1. 隨着搖籃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.runtime.collect { it.isDirectory() ? it : zipTree(it) } 
    } { 
     exclude "META-INF/*.SF" 
     exclude "META-INF/*.DSA" 
     exclude "META-INF/*.RSA" 
    } 
    with jar 
} 

把它添加到標準的組裝或建造任務,添加:

artifacts { 
    archives fatJar 
} 
5

要生成一個主可執行類脂肪JAR,避免簽名JAR問題,我建議gradle-one-jar plugin。一個簡單的插件,使用One-JAR project

使用方便:

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' 
}