2011-02-02 22 views
88

Tengo una creación multiproyecto y puse una tarea para construir un jar gordo en uno de los subproyectos. Creé la tarea similar a la described in the cookbook.Uso de Gradle para crear un jar con dependencias

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

Correr el resultado es el siguiente error:

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

No estoy seguro de lo que significa este error. I also reported this on the Gradle JIRA in case it is a bug.

Respuesta

133

he publicado a solution en JIRA contra 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

tuve que modificar esto para configurations.runtime.collect para mi proyecto ya que tengo dependencias de tiempo de ejecución así. – vextorspace

+0

Tuve que agregar 'def mainClassName' para que el código funcionara ... Estaba recibiendo No se pudo establecer la propiedad desconocida 'mainClassName' para el proyecto raíz – hanskoff

+1

¿Cómo se manejan las colisiones de nombre de archivo? Se sobrescribirán los archivos en la misma ruta en diferentes JAR. – waste

52

Si desea que la tarea jar comportarse normalmente y un fatJar tarea additinal, utilice la siguiente:

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

La parte importante es with jar . Sin él, las clases de este proyecto no están incluidas.

+1

Consulte también el siguiente problema si está utilizando archivos jar firmados para incluirlos y ejecutarlos en un problema con firmas: http://stackoverflow.com/questions/999489/invalid-signature-file-when-attempting-to-run-a- jar –

+0

Esto funciona bien, excepto que si trato de modificar el archivo de manifiesto, obtengo dos archivos de manifiesto. – Sundae

+0

Merece la pena señalar (como lo incluí en mi reseña [aquí] (http://stackoverflow.com/a/25095068/1040915)) que, si solo desea la tarea fatJar, simplemente puede establecer 'from files ({ configuraciones ... zipTree (it)}}, sourceSets.main.java) '- o, según corresponda. – scubbo

6

Esto funciona bien para mí.

Mi clase principal:

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

} 

Y es el contenido de mi archivo 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 
} 

y escribo lo siguiente en mi consola:

java -jar ProyectoEclipseTest-all.jar 

Y la salida es excelente:

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 simple

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

Si estás acostumbrado a la hormiga entonces usted podría intentar lo mismo con Gradle también:

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

La respuesta por @felix casi me llevó allí. Tenía dos cuestiones:

  1. Con Gradle 1.5, la etiqueta de manifiesto no fue reconocido dentro de la tarea fatJar, por lo que el atributo de la clase principal no podía ser directamente fijado
  2. el frasco tenía archivos de META-INF externos en conflicto.

La siguiente configuración resuelve este

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 
} 

Para añadir esto a la norma ensamblar o construir tarea, añadir:

artifacts { 
    archives fatJar 
} 
+3

Esto también solucionó un problema que tenía donde uno de mis frascos de dependencia se firmó. Los archivos de firma se pusieron en el archivo META-INF de mi jar, pero la firma ya no coincidía con el contenido. – Flavin

+0

Agradecimiento especial para 'artefactos': exactamente lo que estaba buscando. – AlexR

+0

Cuando ejecuta' gradle fatJar' las dependencias de tiempo de ejecución no parecen compilarse, por lo que no se pueden copiar. – mjaggard

5

Para generar un JAR de grasa con una clase ejecutable principal, evitando problemas con los JAR firmados, sugiero gradle-one-jar plugin. Un plugin simple que usa el One-JAR project.

Fácil de usar:

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