I am writing a custom Ant task to handle some business logic, and I want to call the Move Ant task.
I presume I would use the Execute java class, but I'm having trouble figuring it out.
Am I going in the right direction, or can you not call one class from another in an Ant way?
For your task, you wanna call the Move task. So you want to move some files.
Generally, when you are coding in Java, you should avoid calling built-in Ant tasks, as they usually have poor performance. For example, you can either use File.renameTo() method from java.io.File or Files.move() from java.nio.file.Files (JDK7 only).
If you do want to take advantage of some Ant things, like <fileset>, you may want your task to be able to take Move task as a nested task in build xml. Just make your task a TaskContainer and do some filtering in its method.
Of course, you can also just import the Move task, set all the needed properties, and the call its execute() method. But I do not like that.
The above answer does not answer the original question "Can you execute an Ant task from within a custom Ant task?"
The answer is definitely yes.
Here is an example with Copy. Move is similar. And while File.renameTo() may have better performance than calling an Ant Move task, there are definitely reasons why you might want to invoke an Ant task from within a custom Ant task, especially in cases where no suitable JRE alternative exists. The Ant API is very extensive and provides a great number of useful tasks. Furthermore, you may want invoke a custom Ant task from within a different custom Ant task.
See also http://www.jajakarta.org/ant/ant-1.6.1/docs/ja/manual/api/org/apache/tools/ant/taskdefs/package-summary.html
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.taskdefs.Copy;
...
// set up the Strings inputPath and outputPath appropriately...
...
try{
FileSet inputSet = new FileSet(); // what to copy FROM
inputSet.setDir(new File(inputPath));
Copy copyTask = new Copy();
copyTask.setProject(getProject());
copyTask.setTodir(outputPath); // where to copy TO
copyTask.setFailOnError(true);
copyTask.addFileset(inputSet);
copyTask.execute();
}
catch(Exception e){
String msg = "Exception while invoking Copy task with inputPath=\"" + inputPath + "\" and outputPath=\"" + outputPath + "\": " + e.toString();
throw new BuildException(msg, e);
}
Related
Is there a way to define a task in Ant that always gets executed at the end of every run? This SO question provides a way to do so, at the start of every run, before any other targets have been executed but I am looking at the opposite case.
My use case is to echo a message warning the user if a certain condition was discovered during the run but I want to make sure it's echoed at the very end so it gets noticed.
use a buildlistener, f.e. the exec-listener which provides a taskcontainer for each build result
( BUILD SUCCESSFUL | BUILD FAILED ) where you can put all your needed tasks in, see :
https://stackoverflow.com/a/6391165/130683
for details.
It's an interesting situation. Normally, I would say you can't do this in an automated way. You could wrap Ant in some shell script to do this, but Ant itself really isn't a full fledge programming language.
The only thing I can think of is to add an <ant> call at the end of each task to echo out what you want. You could set it up, that if a variable isn't present, the echo won't happen. Of course, this means calling the same target a dozen or so times just to get that final <echo>.
I checked through AntXtras and Ant-Contrib for possible methods, but couldn't find any.
Sorry.
Wrap your calls in the sequential container.
http://ant.apache.org/manual/Tasks/sequential.html
I have to look for a .xls(say test-results.xls) in a given folder. If not available, it should wait for 60 minutes for *.xls creation before timing-out. The test-execution target will meanwhile create this test result file.
I am trying to use ant: waitfor task and the associate "available" task for filename. But "available" task expects a specific filename(eg: test-results.xls). I can't have that as the file is appended with time-stamp(eg: test-result_08-22-2012 9:45 PM.xls). I tried using fileset task but it says fileset can't be used within waitfor task.
I have to use ant: waitfor task and look for a file with a particular pattern(say: test-result*.xls or *.xls). Please let me know if that's possible or is there an alternative to waitfor task for this particular scenario?
Hi you can use this combination ant-contrib PropertyRegex and waitfor task. We have used this combination for our requirement which is similar to yours.
I have an extension-point defined in ant :
<extension-point name="foo"/>
A lot of tasks contribute to this point in several imported ant files :
<bindtargets targets="bar" extensionPoint="foo" />
However I'm kinda lost as to exactly which tasks are contributing. Is there a way to have ant report the tasks that would be triggered by a given extension point ? More generaly, is there a way to display the "call-graph" (or simply the list of dependencies) of an ant task ?
I tried using verbose options for ant (-v and such), with no luck.
Thanks
First of all, you can try to debug the ANT process in your IDE using remote debugging by adding some parameters to ANT_OPTS (mine is set in ~/.profile):
http://blog.dahanne.net/2010/06/03/debugging-any-java-application/
And profiling may help. I found project Antro on ANT Wiki...
http://sourceforge.net/projects/antro
Maybe you can try it out. The project is said to be designed for ANT, which looks promising in solving your problem.
Also you can use Yourkit Java Profiler to do a CPU profiling. YJP can show the call graph of a java application, but I'm not sure if one can find out which are ANT targets.
The following document shows how to start a java application with YJP agent.
http://www.yourkit.com/docs/95/help/agent.jsp
I know of 2 ways to get this information:
You can get the effective target/extension-point invocation sequence from Ant's console logger. To do this, place Ant's logging facility into verbose mode by passing -verbose on the command line to Ant. There are two lines, one after the other, that dump to the console immediately before most targets as they are invoked in your build script:
A line that shows a summary of the targets in the call sequence starting with the text, Build sequence for target(s) 'artifact' is [...].
A line showing the detailed call sequence (nested targets and antcalls included). This line starts with the text, Complete build sequence is [...]. This listing considers, as much as reasonably possible, the evaluation of any if and unless attributes of each target listed at the point the line is logged to the console.
Simply invoke your Ant build as you would normally with the -verbose option and your console should have the information you're looking for.
You can get a pictorial representation of the call sequence using a tool called Grand. However, it hasn't been updated for quite some time and thus doesn't support extension-points (which is what you're concerned with here). It will interpret antcall's, ant, and depend'encies. It doesn't evaluate the if and unless attributes but simply identifies potential execution sequence - more of a dependency hierarchy than an actual call graph. The project is on Github so an update to support extension-points may not be too difficult.
The graphic is rendered using Graphviz.
For an actual call sequence, use option 1.
This is pretty sloppy, but it works. Ant is actually pretty easily scripted, and if you are using at least Java 6 (or it might be Java 7), javascript support is built in and thus can be used right out of the box. This defines a task that will echo the dependencies of any target in call order:
<scriptdef name="listdepends" language="javascript">
<attribute name="target"/>
<![CDATA[
var done = [];
var echo = project.createTask("echo")
function listdepend(t) {
done.push(t.getName());
var depends = t.getDependencies();
while (depends.hasMoreElements()) {
var t2 = depends.nextElement();
if (done.indexOf(t2)==-1) listdepend(project.getTargets().get(t2));
}
echo.setMessage(t.getName());
echo.perform();
}
var t = attributes.get("target");
if (t!=null) {
var targ = project.getTargets().get(t);
listdepend(targ);
}
]]>
</scriptdef>
In your case, you can create a new target (or not) and call it like so:
<target name="listfoo">
<listdepends target="foo"/>
</target>
As I said, this is somewhat sloppy. It probably isn't very fast (although unless your target triggers thousands of others, it probably isn't noticeably slow). It won't handle antcall tasks (although it could be modified to do so easily) or respond to if and unless attributes. If dependencies nest too far, it may hit a recursion depth limit (but I doubt any project nest them deep enough).
The array is used to make sure that each dependency is listed once (ant would only run them once).
What is the main difference between for and for each.
I am working with websphere mqfte to transfer files using ant scripts.
I need my files to renamed and send to another folder as below :
eg: src : \src\*.txt the files in destination should be \dest\kk_*.cpp (The * indicates the filename. Need all the files to to renamed as follows).
Can anyone help me on this???.
The main difference between for and foreach task from antcontrib =
for uses sequential like macrodef whereas
foreach opens a new project scope for each iteration - like other tasks as
ant, antcall, and subant.
That means because of performance issues the use of for task should be favored.
For your renaming problem => you should use copy or move task with
a nested mapper as already stated by other fellows.
What's the reason to act against standard ant usage !?
btw. because antcontrib development seems to be dead - last release back in 2006 :
there's a new ant addon with similar features => ant flaka
Use the copy task with a glob or regexp mapper. Don't know what for and for each have to do with this question, though.
The for and foreach tasks are not part of core Ant, most likely they are the ones in the ant-contrib collection.
According to the ant-contrib for task docs:
This task is the same as the <foreach>
task, except that
* it uses a nested sequential for each iteration; and
* it implements an additional "keepgoing" attribute.
<for> makes use of ant's macrodef
task, so the #{} notation is used for
parameter substition.
I am reading a file in ant and loading the properties through loadproperties. I am interested in using the value of a specific property, whose name is not known. I know that it follows a pattern because that is how I load the property.
I can echoproperties and see that it is being loaded.
But I dont know how to access its value, given that its name is actually a pattern rather that hardcoded.
How can I access this property's value to do some processing.
I hope this is clear. Please ask if I need to clarify some more.
Take a look at ant-contrib package. Its propertycopy task will do what you need. If you need to resolve an arbitrary number of properties following an established pattern, you would use ant-contrib's propertycopy in conjunction with ant-contribs "for" task.
http://ant-contrib.sourceforge.net/tasks/tasks/index.html
You should use Ant's script task.
I suggest using the beanshell script since it is pure java.
For example, to print all properties for your project, use the following:
<target name="echoprops">
<script language="beanshell">
System.out.println("All Properties: " + project.getProperties().keySet());
</script>
</target>
It should be easy to modify the above script to get the property you want.
To use this task, you will need to run the following in $ANT_HOME first:
ant -f fetch.xml script -Ddest=user
That will download all required optional jars to ~/.ant/lib .