A clean way to combine multiple cans? Ant preferred

I have performance dependencies on some external jars that I would like to โ€œrepaintโ€ in one jar. These external dependencies are stored in the external_jars directory, and I would like to be able to not list them all (i.e. no need to change build scripts if the dependencies change). Any thoughts?

Google gave me a good answer on how to do this - if you don't mind, to list each jar as a dependency:

http://markmail.org/message/zijbwm46maxzzoo5

Roughly speaking, I want something along the lines of the following, which would combine all the banks in the lib directory in out.jar (with some normal rewrite rules).

jar -combine -out out.jar -in lib/*.jar 
+54
java jar ant
Feb 05 '09 at 11:01
source share
11 answers

Just use zipgroupfileset with Ant zip Task

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

This will smooth out the contents of all jar library libraries.

+53
Feb 05 '09 at 21:38
source share
โ€” -

Vladimir's answer is correct, but I feel that what he offers involves repackaging all the jars in one big out.jar, which is then loaded into the Ant Jar task as one <zipfileset> or something like that. This two-step approach is not needed. I'm not sure if this is related to the Ant version, but I have Ant 1.7.1, and the task <jar> understands <zipgroupfileset> , which allows you to directly download all the contents of third-party banks.

 <jar destfile="MyApplication.jar"> <zipgroupfileset dir="lib" includes="*.jar" /> <!-- other options --> <manifest> <attribute name="Main-Class" value="Main.MainClass" /> </manifest> </jar> 
+65
Oct 24 '09 at 21:14
source share
+23
Feb 05 '09 at 11:03
source share

Try to extract the JAR to the sorting directory first:

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

Where ${marshall.dir} is the temporary directory, ${external.jar.dir} is the place where you save the JAR, and ${combined.jar} is the target JAR.

+7
Feb 05 '09 at 12:55
source share

If you use maven, why not? :) Just use the maven-shade plugin, it works like a charm!

  <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
Jan 31 2018-12-12T00:
source share

This is my decision:

 <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
Jan 14 '11 at 13:40
source share

Do you consider using Maven or some other system that automatically manages your dependencies? Then you will not need to indicate where each library is located, what their names are and what transit dependencies your direct dependencies have. You simply indicate in one place what the dependency is and its version, and the system will take care of loading the libraries, setting the class path and creating the project.

+1
Feb 05 '09 at 18:50
source share

The question answered well. I wanted to mention one tool that comes in handy - One-Jar . One-Jar processes resources more cleanly (saving them all). This is more useful if the code needs to process MANIFEST files.

Sample XML copied from a website ..

 <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
Mar 14 '12 at 5:11
source share

Well, I don't do much programming, but something simpler worked for me ... if it was a matter of combining jar files into one. Of course, this is a manual, dirty solution. I simply dispersed all the traces ... and then created a new tar file, adding all the directories formed by expanding to a new tar file. it worked.

0
Mar 18
source share

Maven or other build tools cannot "manage" the resolution of multiple versions of class files. In fact, Maven causes these problems primarily due to the transitive inclusion of all jar files down that are not explicitly required for the project.

Assume that somewhere in the transitive closure of the project (all the libraries and modules needed for the project, and all its dependent projects, recursively) there are two versions of the class file. How could Maven possibly find out which one is โ€œcorrectโ€? which one was intended by the programmer?

This is not possible because this information was lost when explicit dependencies were thrown in favor of transitive ones (to preserve XML input).

0
Apr 15 2018-10-15T00:
source share

If you build using ant (I use ant from eclipse), you can simply add additional jar files saying ant to add them ... Not necessarily the best method if you have a project supported by several people, but it works for one human and simple.

for example, my goal, which created the .jar file:

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

I just added one line to do this:

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

Where

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

there was a gear with external jars. And that ... You can add some zipgroupfileset tags.

0
Apr 25 '12 at 18:41
source share



All Articles