Forma limpia de combinar múltiples frascos? Preferiblemente usando Ant


Tengo dependencias de tiempo de ejecución en algunos jars externos que me gustaría "rejar" en un solo jar. Estas dependencias externas se almacenan en un directorio external_jars, y me gustaría poder no tener que enumerarlas todas (es decir, no tener que cambiar mis scripts de compilación si mis dependencias cambian). ¿Alguna idea?

Google me dio una buena respuesta sobre cómo hacer esto - si no te importa enumerar cada frasco como un dependencia:

Http://markmail.org/message/zijbwm46maxzzoo5

Aproximadamente, quiero algo en la línea de lo siguiente, que combinaría todos los frascos en el directorio lib en out.jar (con algunas reglas de sobrescritura sanas).

jar -combine -out out.jar -in lib/*.jar
 56
Author: martin clayton, 2009-02-05

11 answers

Simplemente use zipgroupfileset con la tarea Zip Ant

<zip destfile="out.jar">
    <zipgroupfileset dir="lib" includes="*.jar"/>
</zip>

Esto aplanará todo el contenido de las bibliotecas jar incluidas.

 53
Author: Vladimir,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-24 00:03:28

La respuesta de Vladimir es correcta, pero siento que lo que sugiere implica volver a empaquetar todos los frascos en una salida grande.tarro, que luego se alimenta a la tarea Tarro Hormiga como un solo <zipfileset> o algo así. Este enfoque en dos etapas es innecesario. No estoy seguro de si esto está conectado con la versión Ant, pero tengo Ant 1.7.1, y su tarea <jar> entiende <zipgroupfileset>, lo que permite alimentar todos los contenidos de jars de terceros directamente.

<jar destfile="MyApplication.jar">
  <zipgroupfileset dir="lib" includes="*.jar" /> 
  <!-- other options -->
  <manifest>
    <attribute name="Main-Class" value="Main.MainClass" />
  </manifest>
</jar>
 65
Author: nightingale,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-24 21:14:27

Puedes echar un vistazo a jarjar:

Http://code.google.com/p/jarjar /

 23
Author: Staale,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-05 11:03:41

Intenta extraer tus JARS a un directorio de marshalling primero:

<target name="combine-jars">
    <mkdir dir="${marshall.dir}"/>
    <unzip dest="${marshall.dir}">
        <fileset dir="${external.jar.dir}">
            <include name="**/*.jar"/>
        </fileset>
    </unzip>
    <jar destfile="${combined.jar}" basedir="${marshall.dir"}>
    <delete dir="${marshall.dir}"/>
</target>

Donde ${marshall.dir} es un directorio temporal, ${external.jar.dir} es donde guardas el JAR, y ${combined.jar} es el JAR objetivo.

 9
Author: David Grant,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-05 12:55:14

Si utilizas maven, ¿por qué no lo harías ? :) Solo tiene que utilizar el maven-sombra-plugin, funciona como un encanto !

  <project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>1.5</version>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>shade</goal>
            </goals>
            <configuration>
              <transformers>
                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                  <mainClass>com.YOUR_COMPANY.YOUR_MAIN_CLASS</mainClass>
                </transformer>
              </transformers>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
  ...
</project>
 4
Author: Mozart Brocchini,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-13 22:12:45

Esta es mi solución:

<target name="-post-jar">
    <echo>Packaging ${application.title} into a single JAR</echo>

    <jar destfile="${basedir}${file.separator}${dist.dir}${file.separator}_${ant.project.name}_.jar">
        <zipgroupfileset dir="${basedir}${file.separator}${dist.dir}" includes="${ant.project.name}.jar"/>
        <zipgroupfileset dir="${basedir}${file.separator}${dist.dir}${file.separator}lib" includes="*.jar"/>
        <manifest>
            <attribute name="Main-Class" value="${main.class}"/>
        </manifest>
    </jar>
</target>
 2
Author: Matt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-02 06:54:18

¿Ha considerado usar Maven o algún otro sistema que administre sus dependencias automáticamente? Entonces no necesitará especificar dónde se encuentra cada biblioteca, cuáles son sus nombres y qué dependencias transitivas tienen sus dependencias directas. Solo se indicaría en un solo lugar cuáles son la dependencia y su versión, y el sistema se encargaría de descargar las bibliotecas, configurar el classpath y construir el proyecto.

 1
Author: Esko Luontola,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-05 18:50:32

La pregunta está bien contestada. Quería mencionar una herramienta que me parece útil-One-Jar. One-Jar maneja los recursos de manera más limpia (manteniendo todos ellos). Esto es más útil si el código necesita procesar archivos de MANIFIESTO.

XML de ejemplo copiado del sitio web..

<import file="one-jar-ant-task.xml"/>   

    <target name="hello" depends="init">
        <!-- Build lib.jar -->   
        <javac destdir="${classes.dir}/lib">
            <src path="${lib.dir}" />
        </javac>
        <jar destfile="${build.dir}/lib.jar" >
            <fileset dir="${classes.dir}/lib"/>
        </jar>   
        <!-- Build classes for main.jar -->   
        <javac destdir="${classes.dir}/src">
            <src path="${src.dir}" />
            <classpath path="${build.dir}/lib.jar"/>   
        </javac>
        <!-- Construct the One-JAR file -->   
        <one-jar destfile="hello.jar" manifest="hello.mf">
            <main>
                <!-- Construct main.jar from classes and source code -->
                <fileset dir="${classes.dir}/src"/>
            </main>
            <lib>
                <fileset file="${build.dir}/lib.jar" />
            </lib>
        </one-jar>
        <echo>
          Now you can run the Hello One-JAR example using 
          $ java -jar hello.jar
        </echo>   

    </target>
 1
Author: Jayan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-14 05:11:59

Si está construyendo con ant (estoy usando ant de eclipse), puede agregar los archivos jar adicionales diciéndole a ant que los agregue... No necesariamente el mejor método si tiene un proyecto mantenido por varias personas, pero funciona para un proyecto de persona y es fácil.

Por ejemplo mi objetivo que estaba construyendo el.el archivo jar era:

<jar destfile="${plugin.jar}" basedir="${plugin.build.dir}">
    <manifest>
        <attribute name="Author" value="ntg"/>
        ................................
        <attribute name="Plugin-Version" value="${version.entry.commit.revision}"/>
    </manifest>
</jar>

Acabo de añadir una línea para hacerlo:

<jar ....">
    <zipgroupfileset dir="${external-lib-dir}" includes="*.jar"/>
    <manifest>
        ................................
    </manifest>
</jar>

Donde

<property name="external-lib-dir" value="C:\...\eclipseWorkspace\Filter\external\...\lib" />

Era el dir con las jarras externas. Y eso es todo... Puede agregar múltiples etiquetas zipgroupfileset también.

 1
Author: ntg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-25 18:48:29

Bueno, no estoy tan metido en la programación, pero algo más simple funcionó para mí...si la pregunta significaba - la combinación de archivos jar en uno. Por supuesto, esto es manual, solución sucia. Acabo de desentrañar todos los alquitranes...y luego..creado un nuevo archivo tar, añadiendo todos los directorios formados por untarring-in al nuevo archivo tar. funcionó.

 0
Author: Sowmya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-18 03:57:26

Maven u otras herramientas de compilación no pueden "administrar" la resolución de varias versiones de archivos de clase. De hecho, Maven causa estos problemas en primer lugar, a través de la inclusión transitiva de todos los archivos jar posteriores que no son explícitamente requeridos por un proyecto.

Supongamos que en algún lugar del cierre transitivo de un proyecto (todas las bibliotecas y módulos requeridos por el proyecto, y todos sus proyectos dependientes, recursivamente) hay dos versiones de un archivo de clase. ¿Cómo podría Maven posiblemente ¿sabes cuál es la 'correcta'? ¿cuál fue la intención del programador?

No puede porque esta información se perdió cuando las dependencias explícitas se desecharon en favor de las transitivas (para guardar la escritura XML).

 0
Author: hans anderson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-15 08:56:47