Ant tasks don't run IN IzPack installer - ant

.
Hello, everyone
I'm studying IzPack as a tool to be used in a future project and I'm really enjoying it. It's as flexible as I need and makes the process much more easy. I have even submmited a silly pull request at github with a modification I needed to my purposes. Who knows?
Although I don't find it particularly complicated, I've been stuck trying to use a resource for some days. I need that certain Ant Tasks to be executed in certain points of the installation process (right before everything is unpacked is the really one that matters) and that is not working, besides all the efford. :(
My current state, that seems right looking at examples, is the following:
[ My current use of this is based on an example I found here (the docs don't clear too much when It cames to these kind of Actions.]
In my definitions xml file, I included some things:
First, the AntActionsSpect.xml and the .jars, followed by the listeners:
<resources>
...
<res id="AntActionsSpec.xml" src="specs/AntActionsSpec.xml" />
...
</resources>
<jar src="libs/ant/ant.jar" stage="both" />
<jar src="libs/ant/ant-launcher.jar" stage="both" />
<listeners>
<listener classname="AntActionInstallerListener" stage="install" />
<listener classname="AntActionUninstallerListener" stage="uninstall" />
</listeners>
<pack name="test_app" required="yes" installGroups="Application Core">
...
In the specs/AntActionsSpec.xml file, I have the following:
<pack name="test_app">
<antcall order="beforepacks" quiet="no" verbose="yes" buildfile="$INSTALL_PATH/ant-tasks.xml">
<property name="INSTALL_PATH" value="$INSTALL_PATH" />
<target name="touch_beforepacks" />
</antcall>
</pack>
And the ant-tasks.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<target name="touch_beforepacks">
<touch file="$INSTALL_PATH/beforepacks.txt"/>
</target>
</project>
Nothing special here, just creating a dumb file.
The ant-tasks.xml is unpacked right before anyone else. Everything builds with no error, even if I create one "mistake" at AntActionsSpec or ant-tasks.xml, what suggests me that they aren't even been loaded, though if I mess with the path where the definitions file has them, the build will fail.
I would like some help addressing that. I'm probably making some stupid little error and just can't see it by myself. If any of you could provide an example of a running build, that would be sweet.
If I can give any more information, please, let me known so I can update the question.
Thank you very much.

Just found it using a forum on a Google Groups discussion: [izpack-user] Quick question on variable substitution.
Unfortunattly the I will conclude that the docs are misleading. The docs in
"AntActionInstallerListener and AntActionUninstallerListener" until this date are stating that I should use this listener configuration:
<listeners>
<listener classname="AntActionInstallerListener" stage="install" />
<listener classname="AntActionUninstallerListener" stage="uninstall" />
</listeners>
That is what is up there, in the question. Comparing my XML code with the one in the Google Groups discussion, I found a different use of it:
<listeners>
<listener installer="AntActionInstallerListener"
uninstaller="AntActionUninstallerListener" />
</listeners>
In fact, that is the instruction given in the other wiki: Ant Actions (InstallerListener and UninstallerListener), what points out that I something can be wrong under the hood, but that is a story to another episode.
That just works. The Ant tasks are executed properly. :)
I just could not find where freaking Codehaus will allow me to grab a login and edit the docs wiki. >:( . If someone could endorse-me with some testing and then adjust the wiki for future happiness or just give a link to this tired programmer, I'd be happy.

Related

How to resolve 7-zip's 'Warnings: Headers Error' from .zip created by Ant build?

I have code for creating zip file in ant build script.
<target name="zip-dist" description="archiving artifacts">
<zip destfile="${artifacts}/${zipfile}.zip" update="false" basedir="${target.dist}" includes="*.xyz-*" />
</target>
When file is being extracted using win zip right click -> Extract All... there's no warning, but while extracting with 7-zip showing 'Warnings: Headers Error' but its successful.
I know this has no effect on the output as its just a warning so suggested users to ignore it or use win-zip method.
But trust me it is impossible to make them understand and they all are keep on eating my head.
There are many users and I am banging my head repeating same thing again and again. Still they want it to be fixed.
Can I use any attribute in ant-zip target or should I use any different zipping technique in ant build?
I have searched multiple online sources, this is last hope!
Please help.
I had the same issue.
Fixed adding only one attribute, to force Zip64 extensions:
zip64Mode="always"
Try and should work for you too.
Instead of regular zip target used 7-zip to create zip.
<property name="7z.exe" value="C:/Program Files/7-Zip/7z.exe" />
<target name="zip-dist" description="archiving artifacts">
<exec executable="${7z.exe}">
<arg value="a" />
<arg value="-tzip" />
<arg value="${artifacts}/${zipfile}.zip" />
<arg value="${target.dist}/*.xyz-*" />
</exec>
</target>
As 7-zip includes all necessary information regarding header, so that warning will not occur.
Of course, 7-zip must be available in system.

Using Apache Ant to Delete All But Most Recent 3 Directories

I have a scenario in which there is an "archive" directory that contains various subdirectories. I only want to keep the most recent three subdirectories. So, for example I have:
archive/
subA/ [created 1-May-2018]
subB/ [created 2-May-2018]
subC/ [created 3-May-2018]
subD/ [created 4-May-2018]
subE/ [created 5-May-2018]
In other words, I want to be able to select subA and subB (on the basis of their filesystem dates) and delete them -- including all files and subdirectories within them. I can easily do a Python script that does this, but would prefer a pure-Ant solution.
Based on another StackOverflow question (How to delete all but latest 2 files using Ant), I have tried:
<resources id="deleteDirs">
<allbutlast count="3" >
<sort>
<date />
<resources>
<dirset dir="${dir.archive}" includes="*" />
</resources>
</sort>
</allbutlast>
</resources>
<echo message="Delete directories: ${toString:deleteDirs}" />
<delete verbose="true">
<resources refid="deleteDirs" />
</delete>
However this and any other variations I have come up with do not work. Note, however, that the deleteDirs refid when printed out does show what I want selected, but the delete task quietly ignores it.
In briefly examining the source for the delete task, there are comments to the effect that the delete was at some point refactored to also perform the deprecated deltree task (which apparently cannot wrap around a resource, dirset, or path). So, I am guessing that when deltree was brought into delete it still only works with the form:
<delete dir="DIRNAME"/>
and not when wrapping a resource collection.
Is there a pure Ant way to essentially do:
<deltree dir="${dir.archive}/subA" />
<deltree dir="${dir.archive}/subB" />
However, without hard-coding my selection(s) in deltree tasks and allowing Ant to select all but the most recent three directories based on date.
I got stuck on the same problem. I am shocked that this problem is not solved for long. Apparently task does not work with resource collection of type . The only solution to the problem I could figure out is to use ant-contrib and do the follwing:
<for param="folder">
<path>
<allbutlast count="${to.keep.count}">
<sort>
<dirset dir="${dir.archive}" includes="*"/>
</sort>
</allbutlast>
</path>
<sequential>
<delete dir="#{folder}"/>
</sequential>
</for>
If anybody can suggest a solution without using Ant-Contrib, I will be (and I believe not only me) very very grateful.
Of course the perfect solution would be to make this work as follows:
<delete verbose="true">
<allbutlast count="${to.keep.count}">
<sort>
<dirset dir="${dir.archive}" includes="*"/>
</sort>
</allbutlast>
</delete>
but unfortunately this does not work.

In ant, how does one create and use a 'library' of targets?

To eliminate redundancy in my ant build.xml files, I decided out-factor the repeated targets into mytargets.xml file, publish it to to the artifact repository, and then import it in the following way:
<import>
<url url="http://mycompany.com/artifacts/mycompany.com/mytargets/1.2.3/mytargets-1.2.3.xml"/>
</import>
There are two things I don't like about this approach:
mytargets-1.2.3.xml never appears anywhere on the disk where I can easily look at it.
I absolutely need access to http://mycompany.com/artifacts in order to do anything in the project---it completely undermines offline work.
So, I tried creating a setup target to fetch a local copy of mytargets.xml and adjusted my <import> to use this local copy.
<import file="${basedir}/antlib/mytargets/mytargets.xml"/>
However, as you have probably guessed, I cannot even execute my setup my target after adjusting my <import> in this way because the file does not yet exist:
Buildfile: /home/me/myproject/build.xml
BUILD FAILED
/home/me/myproject/build.xml:265: Cannot find /home/me/myproject/antlib/mytargets/mytargets.xml imported from /home/me/myproject/build.xml
Adding optional="true" to the <import> only defers the problem to the first target that depends upon mytargets.xml.
I looked at https://ant.apache.org/manual/Types/antlib.html, but this approach does not appears to permit you to define a <target>.
So, how does someone share bits of ant XML across multiple projects? Am I already doing it the 'one true way'? Or, is there a better way?
If you're mainly just trying to avoid download the remote copy when you have a local copy already available, you can try something like this:
<condition property="mytargets.xml.available">
<available file="${basedir}/antlib/mytargets/mytargets.xml" />
</condition>
<target name="setup" unless="mytargets.xml.available">
<get
src="http://mycompany.com/artifacts/mycompany.com/mytargets/1.2.3/mytargets-1.2.3.xml"
dest="${basedir}/antlib/mytargets"
/>
</target>
<target name="main" depends="setup">
<import file="${basedir}/antlib/mytargets/mytargets.xml" />
...
</target>
So, it seems to me that <target> is inherently local and not intended for reuse. On the other hand, <macrodef> appears intended for reuse.
Here is the 'library', mymacros.xml:
<?xml version="1.0"?>
<antlib>
<macrodef name="mymacro">
...
</macrodef>
</antlib>
Here is the client, myproject/build.xml:
<?xml version="1.0"?>
<project name="myproject">
<target name="mytarget">
<mymacro/>
</target>
<taskdef file="mymacros.xml"/>
</project>
Unlike <import> and <include>, <taskdef> will not cause the build to fail immediately if mymacros.xml is missing, which gives you the opportunity to download it.

how to extract the value of a parameter within a parameter and then print in ant

I want to write a code in such a way that I will remove platform from first 3 lines and then take only the platform name and I will suffix that with installer-zip.${platform_name}.
platform.win-x86=true
platform.win-x64=true
platform.unix=false
installer-zip.win-x86=E:\abc.jar
installer-zip.win-x64=E:\def.jar
Now if the selected item is win-x86 then printing installer-zip.${platform_name} should give me E:\abc.jar. I tried ${installer-zip.${platform_name}} and many other things but they are not working
You cannot do this with regular ant, but you can do this with ant-contrib.
In particular, there is a contrib task property-regex.
So something like:
<propertyregex property="$newProperty"
input="$oldProperty"
regexp="^platform\.(,*)$"
select="\1"
casesensitive="false" />
EDIT: and then...
<property name=desiredProperty value="installer-zip.${newProperty}" />
That should give you enough to work out the exact solution you're looking for...

getting error message: "unknown resolver XYZ"

while resolving my ivy.xml, I get a long list of errors, all stating "unknown resolver XYZ". I know the resolver, it is used in the same project but different task.
As far as I understand, the resolver used to create the cache entry is stored and than cannot be determined by the follow-up resolver.
Question is: how can I avoid this? Seeams like this is not really an error, more like a warning since I am able to resolve all dependencies and continue compiling.
Within the same project, the build resolver will not change because it's defined in your ivysettings.xml file.
This is more likely to be a problem with a stale ivy cache. I'd suggest adding an extra target that purges your cache. Useful when encountering this type of problem:
<target name="clean-all" depends="clean" description="Purge ivy cache">
<ivy:cleancache/>
</target>
Run your ant build with the verbose flag (-v). This will give you clear insight into which settings files are being used throughout the resolve process. My wager is you will find your problem fairly easily and it will be along the lines of the settings file you thought you were using is actually not being used.
In my projects, I find this type of thing often happens when a post-resolve task (such as retrieve) triggers a resolve "automatically" and uses the default ivy settings instead of the one I want it to use at the moment. Chances are, your default settings file does not contain the resolvers you're expecting.
To solve these issues, I make a ivysettings-common.xml containing only resolvers. Then, in each of my settings files, I import the common settings and reference the resolvers in the main chain. That looks like:
<ivysettings>
<settings defaultResolver="all-repositories" />
<include file="ivysettings-common.xml" />
<resolvers>
<chain name="all-repositories" returnFirst="true" >
<resolver ref="project" />
<resolver ref="local" />
<resolver ref="hibernate" />
<resolver ref="ibibilo" />
</chain>
</resolvers>
</ivysettings>
From there, I make the common file my default settings, just "in case of emergency" I know all my resolvers can be found (by adding the following to ivy.properties):
ivy.settings.file = ${basedir}/path/to/ivysettings-common.xml
but I explicitly point all my ivy calls to the appropriate settings file, trying to never rely on the default because the whole reason I use ivy+ant is that I prefer precise control over my build process:
I hope all that helps you or someone else.
~gMale

Resources