Ant fails in try catch block - java

In my ANT build I have the following code:
<trycatch reference="exception_ref">
<try>
<echo>Start Building Delivery</echo>
</try>
<catch>
<property name="exception" refid="exception_ref" />
<property name="message" value="Error in trycatch block:${line.separator}${exception}" />
<echo message="${message}" />
<fail message="${message}" />
</catch>
<finally>
<echo>Finally</echo>
</finally>
</trycatch>
Ant says:
Problem: failed to create task or type trycatch
Cause: The name is undefined.
Action: Check the spelling.
Action: Check that any custom tasks/types have been declared.
Action: Check that any / declarations have taken place.
What am I missing here?
// EDIT: I am using ANT in Eclipse

trycatch is a task provided by the Ant-Contrib third-party library. Make sure to download their Jar and have it referenced on the Ant classpath. See this link for how to do this.
On Eclipse, go to Window -> Preferences -> Ant -> Runtime. Under the Classpath tab, add the Ant-Contrib jar using the "Add External JARs..." button. And as mentioned in the link, you need to declare the tasks as follows:
<taskdef resource="net/sf/antcontrib/antlib.xml"/>

Related

ant-contrib post task is not working

I have following task in my build script.
<target name="upload" depends="init">
<taskdef resource="net/sf/antcontrib/antlib.xml"/>
<post to="http://testapp.com/api/builds.format" verbose="true" wantresponse="true" maxwait="0">
<prop name="file" value="./release/temp.ipa"/>
<prop name="notes" value="release notes"/>
</post>
</target>
I run this build script from my mac machine. It gives the following error.
Problem: failed to create task or type post
Cause: The name is undefined.
Action: Check the spelling.
Action: Check that any custom tasks/types have been declared.
Action: Check that any <presetdef>/<macrodef> declarations have taken place.
I already download the ant-contrib-0.3.jar and copied it to ANT_HOME/lib directory where ANT_HOME is /usr/share/ant.
When I search the web here they have asked to use ant-contrib-version.jar as well by building the jar by ourselves using the source. But I could not run the ant script in that source since it throwing some errors.
Can some one guide me to solve this issue.
ant-contrib-0.3.jar is a pretty ancient version of Ant-Contrib. The <post> task doesn't exist in it.
Instead, you'll find <post> in the latest version of Ant-Contrib: ant-contrib-1.0b3

Set target or property to a sub project with Ant/Eclipse on Android

I need to switch to Ant, I managed to compile and install the Android apk file but I didn't manage to transmit the property or a specific target to the referenced library.
My code on the build.xml in the referenced library :
<echo message="Property value is '${foo.dist}'" />
<target name="AfficherVersionAnt">
<echo message="Version d'Ant utilisée : ${ant.version}"/>
</target>
The same code is functional when I put it in the starting package.
<property name="foo.dist" value="true"/>
(and for the target, if I launch with the target)
My ant configuration was generated with :
"C:\Program Files (x86)\Android\android-sdk\tools\android" update project -p "D:\project"
And I don't see where I could set a link
Can someone help me ? I would need global variables or something like this
In eclipse you can define your own variables for ant
Go to external tools configuration > your profile > environnement, and define new environnement variable.

Programmatically executing ANT script in Java

I've built a swing gui in eclipse that is supposed to run a bunch of code previously developed, part of which involves running ant to build the code. When I run the any script outside of the GUI (in the original project) the ant executes correctly and builds the project. However when I try and run ant programmatically it throws errors that look like the project doesn't have the necessary .jars. The code, top of the build.xml, and errors are listed below.
Code Block
File buildFile = new File("lib\\ePlay\\build.xml");
Project p = new Project();
p.setUserProperty("ant.file", buildFile.getAbsolutePath());
DefaultLogger consoleLogger = new DefaultLogger();
consoleLogger.setErrorPrintStream(System.err);
consoleLogger.setOutputPrintStream(System.out);
consoleLogger.setMessageOutputLevel(Project.MSG_INFO);
p.addBuildListener(consoleLogger);
try {
p.fireBuildStarted();
p.init();
ProjectHelper helper = ProjectHelper.getProjectHelper();
p.addReference("ant.projectHelper", helper);
helper.parse(p, buildFile);
p.executeTarget(p.getDefaultTarget());
p.fireBuildFinished(null);
} catch (BuildException e) {
p.fireBuildFinished(e);
}
Build.xml
<?xml version="1.0" encoding="UTF-8"?>
<project name="EPlay" xmlns:ivy="antlib:org.apache.ivy.ant" default="resolve">
<dirname file="${ant.file}" property="ant.dir" />
<property name="scm.user" value="scmrel"/>
<property name="scm.user.key" value="/.ssh/scmrel/id_rsa"/>
<property name="ivy.jar" value="ivy-2.0.0.jar" />
<property name="ivy.settings.dir" value="${ant.dir}/ivysettings" />
<property name="VERSION" value="LATEST" />
<property name="tasks.dir" value="${ant.dir}/.tasks" />
<property name="deploy.dir" value="${ant.dir}/deploy" />
...
<!-- retrieve the dependencies using Ivy -->
<target name="resolve" depends="_loadantcontrib,_getivy" description=" retrieve the dependencies with Ivy">
<ivy:settings file="${ivy.settings.dir}/ivysettings.xml" />
<ivy:resolve file="${ant.dir}/ivy.xml" transitive="false" />
<ivy:retrieve pattern="${deploy.dir}/[conf]/[artifact].[ext]"/>
</target>
And the error
resolve:
BUILD FAILED
H:\eclipse\CLDeploySwing\lib\ePlay\build.xml:66: Problem: failed to create task or type antlib:org.apache.ivy.ant:settings
Cause: The name is undefined.
Action: Check the spelling.
Action: Check that any custom tasks/types have been declared.
Action: Check that any <presetdef>/<macrodef> declarations have taken place.
No types or tasks have been defined in this namespace yet
This appears to be an antlib declaration.
Action: Check that the implementing library exists in one of:
-ANT_HOME\lib
-the IDE Ant configuration dialogs
Total time: 0 seconds
I've looked through my ant installation and it appears everything is there. Like I said, the original project builds successfully if build.xml is run outside of this application.
I would suggest that this is causde because your java program does not have the same classpath, where it is running, as does the normal ant build - and thus the ANT_HOME isn't the right one.
You can make sure that this is correct by passing the right enviornmental variables into the JVM, or simply a call to System.getProperty("ANT_HOME"), to see where your ANT_HOME actually is residing.
I think ${basedir} for your project is not properly calculated.
Add this line to your build.xml
<echo message="basedir='${basedir}'/>
Looking at this line
File buildFile = new File("lib\\ePlay\\build.xml");
It may be that it's 2 levels up ( I know the documentation says that it should be a parent directory of build.xml, but you are not running from the command line ).
rather than load the ivy library using the new method of using the namespace in the project declaration go old school on it.
<path id="ivy.lib.path">
<fileset dir="path/to/dir/with/ivy/jar" includes="*.jar"/>
</path>
<taskdef resource="org/apache/ivy/ant/antlib.xml"
uri="antlib:org.apache.ivy.ant" classpathref="ivy.lib.path"/>
I am doing something in Gradle that requires this
ant.taskdef(name: 'ivy-retrieve', classname: 'org.apache.ivy.ant.IvyRetrieve', classpath: '...path to ivy jar.../ivy-2.2.0.jar')
which in ant would be something like
<taskdef name="ivy-retrieve" classname="org.apache.ivy.ant.IvyRetrieve"/>
I know it's more klunky and simply not as nice as including the namespace declaration but it does remove some of the confusion regarding which libraries on which classpath are being loaded.

Java Ant - how to pass a ProGuard task arguments and use them inside a configuration file?

I have this in my build.xml:
<target depends="build-jar" name="proguard">
<taskdef resource="proguard/ant/task.properties" classpath="tools/proguard4.6/lib/proguard.jar" />
<proguard configuration="ant/proguard.conf" />
</target>
It works fine.
Inside the configuration file (i.e "ant/proguard.conf") I'm trying to access properties defined in this build.xml file but I'm always getting this kind of error:
Value of system property 'jar.final_name' is undefined in '<jar.final_name>' in line 1 of file '.......\ant\proguard.conf'
The error is clear. Question is how I do what I'm trying to?
If I'd do it the "Embedded ProGuard configuration options" way I could use these properties like any other property in build.xml, but I'm trying to keep the files separate.
How do I do that then?
By default, Ant doesn't provide a way to set java system properties for its tasks. You can only specify -D options in the ANT_OPTS system variable when starting Ant itself.
I'll consider supporting the use of Ant properties in referenced ProGuard configurations (being the developer of ProGuard).
For the time being, an acceptable solution might be to specify input and output jars in Ant's XML-style:
<proguard configuration="ant/proguard.conf">
<injar name="${injar}" />
<outjar name="${outjar}" />
<libraryjar name="${java.home}/lib/rt.jar" />
</proguard>
This part of the configuration is more closely tied to the Ant script anyway.

Is there a way to generalize an Apache ANT target?

We have an Apache ANT script to build our application, then check in the resulting JAR file into version control (VSS in this case). However, now we have a change that requires us to build 2 JAR files for this project, then check both into VSS.
The current target that checks the original JAR file into VSS discovers the name of the JAR file through some property. Is there an easy way to "generalize" this target so that I can reuse it to check in a JAR file with any name? In a normal language this would obviously call for a function parameter but, to my knowledge, there really isn't an equivalent concept in ANT.
I would suggest to work with macros over subant/antcall because the main advantage I found with macros is that you're in complete control over the properties that are passed to the macro (especially if you want to add new properties).
You simply refactor your Ant script starting with your target:
<target name="vss.check">
<vssadd localpath="D:\build\build.00012.zip"
comment="Added by automatic build"/>
</target>
creating a macro (notice the copy/paste and replacement with the #{file}):
<macrodef name="private-vssadd">
<attribute name="file"/>
<sequential>
<vssadd localpath="#{file}"
comment="Added by automatic build"/>
</sequential>
</macrodef>
and invoke the macros with your files:
<target name="vss.check">
<private-vssadd file="D:\build\File1.zip"/>
<private-vssadd file="D:\build\File2.zip"/>
</target>
Refactoring, "the Ant way"
It is generally considered a bad idea to version control your binaries and I do not recommend doing so. But if you absolutely have to, you can use antcall combined with param to pass parameters and call a target.
<antcall target="reusable">
<param name="some.variable" value="var1"/>
</antcall>
<target name="reusable">
<!-- Do something with ${some.variable} -->
</target>
You can find more information about the antcall task here.
Take a look at Ant macros. They allow you to define reusable "routines" for Ant builds. You can find an example here (item 15).
Also check out the subant task, which lets you call the same target on multiple build files:
<project name="subant" default="subant1">
<property name="build.dir" value="subant.build"/>
<target name="subant1">
<subant target="">
<property name="build.dir" value="subant1.build"/>
<property name="not.overloaded" value="not.overloaded"/>
<fileset dir="." includes="*/build.xml"/>
</subant>
</target>
</project>
You can use Gant to script your build with groovy to do what you want or have a look at the groovy ant task.

Categories