How to combine two Jar files
Asked Answered
L

7

40

Is it possible to combine two jar files such that in an applet tag I can simply do something like

archive="jarjar.jar/jar1.jar"...  ...archive="jarjar.jar/jar2.jar"... instead of
archive="jar1.jar"... ...archive="jar2.jar"...

I need to only have one jar file so putting two jar files in a folder will not help me.

Lila answered 22/2, 2011 at 15:35 Comment(0)
V
93

Sure, just extract the two jar files and recreate a new one

$ mkdir tmp
$ (cd tmp; unzip -uo ../jar1.jar)
$ (cd tmp; unzip -uo ../jar2.jar)
$ jar -cvf combined.jar -C tmp .

The stuff with tmp ensures that the two existing jars are extracted into a clean directory and then the new one made from that.

Be aware that you may also need to merge any manifest.mf files contained therein, and if there are any also include the '-m' option in that file command.

Vyky answered 22/2, 2011 at 15:40 Comment(1)
This method won't work if you have a case-insensitive filesystem and those jars contain classes with the same name (usually if they were proguarded)Cleveite
H
7

Use zipgroupfileset with the Ant Zip task

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

Might help you.

Heidy answered 22/2, 2011 at 15:44 Comment(0)
T
3

If you are using gradle, just add the following to build.gradle. No plugins required. If you need special options, then go with Fatjar plugin, as initialZero suggests.

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

For Android project, add this to app/build.gradle and run "gradlew superSimpleJar". Find jar in build/libs/app-all.jar

task superSimpleJar(type: Jar) {
baseName = project.name + '-all'
from {

    configurations.compile.findAll {

    it.getName() != 'android.jar'

    }.collect {

    it.isDirectory() ? it : zipTree(it)

    }
 }
}
Troublous answered 27/1, 2015 at 21:30 Comment(3)
* What went wrong: A problem occurred evaluating project ':android-lib'. > Could not find property 'jar' on task ':android-lib:superSimpleJar'.Unfold
Just added an Android version. Good luck, edthethird.Troublous
Same error. "Could not find property 'jar' on task" How can I solve this?Halinahalite
E
1
<?xml version="1.0" encoding="UTF-8"?>
<project name="zip-test" default="zip" basedir=".">

    <target name="zip">
        <zip destfile="out.jar">
            <zipgroupfileset dir="." includes="*.jar"/>
        </zip>
    </target>
</project>

save this code in build.xml file and keep it in same folder where all the jar files to be combined are kept. Open cmd, give path of folder and run command : ant zip.

It will generate out.jar which is combination of all jars.

Enviable answered 4/12, 2017 at 6:35 Comment(0)
A
1

I know it's an old question and I just wanted to add my two cents (no permission to comment yet, so creating a new answer).

I do see the value in sumanth.donthula's answer as the problem for all of us merging jars will be how to deal with the manifest files. In my case I wanted to merge some library files (mainly generated web service client code) into the jar of an application written by me. It was OK to replace the manifests with the one of my own jar.

The simplest way of doing this is taking care of the order in which you unzip the original files (as Alnitak and sumanth.donthula noted).

I wanted to use the zip ant task (thank you, ykombinator, for the idea). It turned out that the only way of controlling the order of compressing/packaging is renaming the files. See my ant target below.

The output directory in my example is called codemodule.dir (I created a FileNet code module). The rest of the names are self-explaining. The important step is renaming the application jar to 0_... to be the 1st in order. This way its manifest will be retained as the duplicate attribute of the zip ant task is set to preserve.

<target name="merge_jars">
    <delete dir="${codemodule.dir}" quiet="true" />
    <mkdir dir="${codemodule.dir}" />
    <copy todir="${codemodule.dir}">
        <fileset dir="${lib.dir}" includes="*.jar"/>
        <fileset dir="${basedir}" includes="${app-name}.jar"/>
    </copy>
    <move file="${codemodule.dir}/${app-name}.jar" tofile="${codemodule.dir}/0_${app-name}.jar"/>
    <zip destfile="${codemodule.dir}/${app-name}-fat.jar" duplicate="preserve">
      <zipgroupfileset dir="${codemodule.dir}">
        <include name="*.jar"/>
      </zipgroupfileset>
    </zip>

Archaeology answered 31/10, 2018 at 10:19 Comment(0)
T
0

Just unzip both jar files, then zip the results into one zip file, and rename this to jar again.

But as adarshr said: Better use the jar command for that.

Transmogrify answered 22/2, 2011 at 15:38 Comment(3)
If you do that, you will lose or overwrite the MANIFEST.MF. It's best to use the jar command.Haydenhaydn
@adarshr: You would have to combine the two manifest files anyway, the jar command doesn't do that automagically. In fact, the jar command of your answer simply ignores the individual manifests and creates a new one.Slipcase
Useful when the remote system you're working on doesn't have the "jar" command and you don't want to set up an ant task for a one-time operation.Maidenhead
H
0

Extract both jars and create a new one works. (Use jar commands shown above). One caveat about manifest file is that you want to extract the jar whose manifest file you want to retain in the last.

Hedley answered 23/5, 2018 at 6:59 Comment(1)
This is the same thing as the answer posted and accepted several years ago?Nosology

© 2022 - 2024 — McMap. All rights reserved.