Ant zip change base dir to zip at different level - java

I have an Ant zip task that looks like this:
<zip basedir="${workspace.dir}"
destfile="${build.output.dir}/test.zip"
includes="${eLibrary}/bin/com/**,
${Common}
excludes="${eLibrary}/lib,
${eLibrary}/src"
>
</zip>
The eLibrary folder has a structure similar to:
`--bin
`--com
`--lib
`--src
I'd like to have the zip file look like this:
`--eLibrary
`--com
`--Common
When the zip is created though it has the following structure:
`--eLibrary
`--bin
`--com
`--Common
I've tried various types of include statements, but they all include the bin folder:
includes="${eLibrary}/bin/**
includes="${eLibrary}/bin/com/**
includes="${eLibrary}/bin
includes="${eLibrary}/bin/com
Changing the basedir won't work because I also need the Common folder included. Any help would be appreciated. Thanks.

You can check the zip task documentation for examples on how to achieve this. The below snippet uses a zipfileset nested element which maps the included entries to the directories inside the archive.
<zip destfile="${build.output.dir}/test.zip">
<zipfileset dir="${eLibrary}/bin/com" prefix="${eLibrary}/com"/>
<zipfileset dir="${Common}" prefix="${Common}"/>
</zip>

Related

Running ant file from its own directory

I have a big ANT script that I use to build-up my environment: total-build.xml.
It calls a bunch of little build.xml files.
However, each of these build.xml files is designed to run in its directory.
For example:
(Project)Build: total-build.xml
(Project)A: build.xml
(Project)B: build.xml
(Project)C: build.xml
total-build.xml looks a bit like:
<ant file="A\build.xml"/>
<ant file="B\build.xml"/>
<ant file="C\build.xml"/>
A\build.xml looks like this:
<copy dir="src" todir="dest"/>
That is, it contains relative paths assumed to be under A. In the example, I expect src == A\src.
I don't want to write absolute paths, as they make things inelegant.
So is there a way to tell ant to run the build.xml file from its own directory.
Suprisingly, I found nothing about this issue using google.
You could use the base dir property for the project tag of each build, like this:
<project name="main" default="help" basedir="..">
...
</project>
and use all relative paths.

wrong JAR packaging in ant file with zipfileset

I'm encountering a strange issue in an ANT file I use for building a Java app. When generating the jar file, eventually I include resource files (images, fonts and config files) in the JAR using zipfileset, like this:
<zipfileset dir="src/res" prefix="res"/>
<zipfileset dir="src/res/images" prefix="res/images" />
<zipfileset dir="src/res/images/Bubbles" prefix="res/images/Bubbles"/>
<zipfileset dir="src/res/images/Clocks" prefix="res/images/Clocks"/>
<zipfileset dir="src/config" prefix="res/config"/>
<zipfileset dir="src/ontology" prefix="res/ontology"/>
To mantain original structure, that looks like this:
res
|-images
| |-Bubbles
| |-Clocks
|-fonts
|-config
|-ontology
Within the JAR, I'm using the prefix parameter in zipfileset. I'm getting duplicated images in res/images and triple images (3 copies of the same image) in any of the res/images/Bubbles and res/images/Clocks folders, which, in the other hand, are 2 and 3 depth levels respectively. res/config and res/ontology are correct, no duplicated files there...a screenshot to see what I mean:
I forgot to mention, but obviously, I only have one instance of each image in every folder. Any ideas what is causing this behaviour?
Regards,
Alex
ant actually does exactly what you told it do. You told him to:
pack all the files under src/res and to map them to res.
pack all the files under src/res/images and to map them to res/images
pack all the files under src/res/images/Bubbles and to them under res/images/Bubbles
Now let's assume that you have a src/res/images/Bubbles/activity_bubble_orange.png files. That file is contained in the first zipfileset, the second zipfileset and the third zipfileset. Ergo it will be packed three times.
To do what you want you need to do a single <zipfileset dir="src/res" prefix="res" /> but filter the contents using includes/excludes filters.
See here: http://ant.apache.org/manual/Types/zipfileset.html where it say that is a type of fileset. and here: http://ant.apache.org/manual/Types/fileset.html to see how you specify includes/excludes filter for a fileset.
You can use the following attribute to include the whole path without hardcoding each sub-directory.
includes="*/.*"
<zipfileset src="examples.zip" includes="**/*.html" prefix="docs/examples"/>
In above example, I'm including *.html recursively.
Sukhbir Dhillon
Addteq

Ant: Split Source Directory into Two Jars

How does one go about creating two Jars from one project source folder? Is that possible, or must I create another project? My project uses Ant right now to generate one Jar. For example, say I want to split up the class files like this:
Jar 1:
com.myproject.Foo
com.myproject.Bar
Jar 2:
com.myproject.FooBar
com.myproject.BarFoo
com.myproject.FooBarFoo
...
See http://ant.apache.org/manual/Tasks/jar.html. You just have to use filesets or includes/excludes inside your jar task to include only the files you want in each jar:
<target name="makeJars">
<jar destfile="jar1.jar"
basedir="classes"
includes="com/myproject/Foo.class, com/myproject/Bar.class"/>
<jar destfile="jar2.jar"
basedir="classes"
includes="com/myproject/FooBar.class, com/myproject/BarFoo.class, com/myproject/FooBarFoo.class" />
</target>

How to combine two Jar files

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.
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.
Use zipgroupfileset with the Ant Zip task
<zip destfile="out.jar">
<zipgroupfileset dir="lib" includes="*.jar"/>
</zip>
Might help you.
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)
}
}
}
<?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.
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.
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.
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>

ant : jar and zipfileset - copy files from one JAR into another

I am currently doing this:
<jar update="yes"
jarfile="${pwd}/dist/${release}_installer.jar">
<zipfileset src="${pwd}/dist/app.jar" includes="com/izforge/izpack/panels/**"/>
<zipfileset src="${pwd}/dist/app.jar" includes="com/xyz/img/logo.png"/>
</jar>
My existing installer JAR gets updated to include the files as needed, extracted from the app JAR.
So far, so good.
However, I want to modify the behaviour such that the path of the image file is different than what is being copied from:
Currently:
com/izforge/izpack/panels/MyIzPanel.class
com/xyz/img/logo.png
What I want:
com/izforge/izpack/panels/MyIzPanel.class
blah/img/logo.png
So I need to copy the files, but use <zipfileset> and <jar> in such a way that I can modify the directory structure.
Is there a way to do this, apart from unzipping the entire contents copying file and then zipping it back up again?
EDIT:
Link to earlier related question: ant task to remove files from a jar
You can use the fullpath attribute:
<zipfileset src="${pwd}/dist/app.jar"
includes="com/xyz/img/logo.png" fullpath="blah/img/logo.img"/>
If you need to copy several files you may want to have a look at the prefix attribute, e.g.:
<zipfileset src="${pwd}/dist/app.jar"
includes="**/*.png" prefix="blah/img"/>
In order to modify the directory structure within the archive on the fly you can use the task in combination with <mappedresources>, eg:
<jar file="target.jar" update="true">
<mappedresources>
<zipfileset src="source.jar">
<include name="com/xyz/img/*.png"/>
</zipfileset>
<mapper type="glob" from="com/xyz/img/*.png" to="bla/img/*.png" />
</mappedresources>
</jar>
You should probably look into zipgroupfileset as explained here.

Categories

Resources