2011-02-02 10 views
88

Ho una build multiprogetto e ho inserito un'attività per creare un jar fat in uno dei sottoprogetti. Ho creato il compito simile a quello described in the cookbook.Uso di Gradle per creare un jar con dipendenze

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

esecuzione il risultato e 'il seguente errore:

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

Non sono sicuro di cosa significa questo errore. I also reported this on the Gradle JIRA in case it is a bug.

risposta

133

ho postato a solution in JIRA contro 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) } 
    } 
} 
+3

ho dovuto modificare questo per configurations.runtime.collect per il mio progetto come ho dipendenze runtime pure. – vextorspace

+0

Ho dovuto aggiungere 'def mainClassName' per far funzionare il codice ... Stavo ricevendo Impossibile impostare la proprietà sconosciuta 'mainClassName' per il progetto root – hanskoff

+1

Come gestite le collisioni dei nomi dei file? I file sullo stesso percorso in JAR diversi verranno sovrascritti. – waste

52

Se si desidera che il compito jar comportarsi normalmente e un compito supplementare in fatJar, utilizzare il seguente:

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

La parte importante è with jar . Senza di esso, le classi di questo progetto non sono incluse.

+1

Vedere anche il seguente problema se si utilizzano giare firmati da includere ed eseguire un problema con le firme: http://stackoverflow.com/questions/999489/invalid-signature-file-when-attempting-to-run-a- jar –

+0

Funziona bene, tranne che se provo a modificare il file manifest, ottengo due file manifest. – Sundae

+0

Vale la pena notare (come ho incluso nella mia scrittura [qui] (http://stackoverflow.com/a/25095068/1040915) che, se si desidera solo l'attività fatJar, è possibile semplicemente impostare 'dai file ({ configurazioni ... zipTree (it)}}, sourceSets.main.java) '- o, come appropriato. – scubbo

6

Questo funziona per me.

La mia classe principale:

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

} 

Ed è il contenuto del mio file 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 
} 

e scrivo quanto segue in mia console:

java -jar ProyectoEclipseTest-all.jar 

E l'output è ottimo:

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

semplice sulution

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

Se siete abituati a formica allora si potrebbe provare la stessa cosa con Gradle troppo:

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

La risposta da @felix quasi mi ha portato lì. Ho avuto due problemi:

  1. Con Gradle 1.5, il tag manifesta non è stata riconosciuta all'interno del compito fatJar, quindi l'attributo Main-Class non poteva essere direttamente fissato
  2. il vaso aveva contrastanti file META-INF esterni.

La configurazione che segue risolve questo

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 
} 

Per aggiungere questo allo standard montare o costruire compito, aggiungere:

artifacts { 
    archives fatJar 
} 
+3

Questo ha anche risolto un problema che avevo dove uno dei miei barattoli delle dipendenze era firmato.I file della firma sono stati inseriti nel META-INF del mio jar, ma la firma non corrispondeva più al contenuto – Flavin

+0

Speciali ringraziamenti per 'artefacts': esattamente quello che stavo cercando – AlexR

+0

Quando si esegue' gradle fatJar' le dipendenze del runtime non sembrano essere compilate, quindi non possono essere copiate. – mjaggard

5

Per generare un JAR grasso con una classe eseguibile principale, evitando problemi con i JAR firmati, suggerisco gradle-one-jar plugin. Un semplice plugin che utilizza lo One-JAR project.

Facile da usare:

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