Display Ant options, properties specified in invocation - ant

I have an Ant buildfile (build.xml) which is called by some application. I would like to know exactly what kind of properties are used to invoke Ant. Therefore I would like to modify the build.xml file to display all properties specified in the call, e.g.:
ant aTarget -Dxslt.parser=SAXON -Dbasedir=aFolder
would display list as below
- target: aTarget
- xslt.parser = SAXON
- basedir=aFolder
Please note that I do not know exactly what is being using to invoke Ant. Therefore, I need to use some sort of a loop get all properties, options.

The simplest thing that comes to mind is to place a line like:
<echo message="Ant invocation is '${sun.java.command}'" />
In the buildfile outside of any target. It'll look something like:
% ant aTarget -Dx=y
[echo] ant invocation is: 'org.apache.tools.ant.launch.Launcher -cp . aTarget -Dx=y'
It shows you what was passed to the Ant Launcher, which might will likely be a little more than what was passed to the ant wrapper script, but should do.
I would avoid trying to parse the line, as you say, you don't know what might be there, and it could quickly get complicated.

Take a look at the <echoproperties> task:
<property name="in.file.prop" value="value2"/>
<echoproperties/>
in.file.prop and its value will be printed. However, over 60 other properties will be printed as well including properties built into Ant.
You can save the results of <echoproperties> to a file and then filter that file with something like a <linecontains> filter.

Related

Set a system property with ant

I have an ant script which has a taskdef and the task creates an https internet connection and somethin with that SSL stuff is wrong. Thus I want to set the system property javax.net.debug=all to get some more information.
In java I would do this using the -D option, but in ant this is used for ant properties which is not the same as a system property.
If this wouldn't be a taskdef but instead a java task, I could use the sysproperty property, but it is no java-task.
Googling for this is frustratingly complicated because ant properties and system properties in ant are so similar that most search results are about the other (or about the java-task).
Obviously I am not the only one with the problem, but other people's questions that I have found (like here) are unanswered or went for hack (like here).
One way to set such a property is the ANT_OPTS system variable. You have to be very carefully to not simply skim over answers on google that state that options can be set that way, because it sounds so much like not what it does:
The documentation says:
ANT_OPTS - command-line arguments that should be passed to the JVM.
For example, you can define system properties or set the maximum Java
heap size here.
Who what have expected that? ANT_OPTS are options for the JVM and not for ant like the name suggests. The var which is used for ant options is called ANT_ARGS.
Now I can launch ant like this: ANT_OPTS="-Djavax.net.debug=all" ant myTarget and can see tons of log output.
(However this leaves the question open whether such a variable can be set using XML).
You can declare system properties in the xml with <sysproperty key="key" value="value"/>.
http://www.java2s.com/Code/Java/Ant/SetsystempropertiesinAntbuildscript.htm
You can use scripting:
<script language="javascript">
java.lang.System.setProperty('myKey', 'myValue');
</script>

property file path changed during ant build

<propertyfile file="${build.dir}/MyProperties.properties">
<entry key="releaseInformation"
type="string"
value="${build.time}"/>
</propertyfile>
When Ant copies my properties file over to the bin directory there is a property in it that has something like "samplePathName=C\:\Users\SomeUser\". But the property from the original file was "samplePathName=C:\Users\SomeUser\". How would the additional backslash end up there? I don't see anything that could possibly cause this to happen. Where should I begin looking other than the build.xml which only contains (relevant) the above line?
This is a common problem - the format of property files is defined by Sun (Oracle). Ant is conforming to this, which is why the escaping happens. There's no way round this using the propertyfile task - that's the way it's intended to work. If the file is genuinely a Java property file, then it shouldn't matter - the escaping should be handled correctly when the file is read.
However if you are hoping to use propertyfile to write a name-value config file that's for something else - where the escaping is not wanted - you'll need to adopt a different approach. As mentioned in the answer to a related question - you might use the Ant replace or replaceregexp tasks for this.

remove relative path of a jar and keep only jar name

I Have a property file which contains list of jars from different paths like this
/gwt/X/2.1.0/gwt-servlet.jar
/gwt/X/2.1.0/gwt-user.jar
/gwt/X/2.1.0/gwt-dev.jar
/gwt/X/2.1.0/gwt-soyc-vis.jar
/log4j/X/1.2.15/log4j-1.2.15.jar
/GWT_LOG/X/3.0.3/gwt-log-3.0.3.jar
/GWT_MATH/X/2.1/gwt-math-2.1.jar
/GWT_MATH/X/2.1/gwt-math-server-2.1.jar
/GWT_Commons_Logging/X/0.3/GWT-commons-logging/gwt-commons-logging-0.3.jar
/GWT_Commons_Logging/X/0.3/GWT-commons-logging/gwt-commons-logging-service-0.3.jar
I have around 1000 jars like this in this list.
I would like to remove relative paths before jar name and out put jar names in a new file some thing like this
gwt-servlet.jar
gwt-user.jar
gwt-dev.jar
gwt-soyc-vis.jar
log4j-1.2.15.jar
gwt-log-3.0.3.jar
gwt-math-2.1.jar
gwt-math-server-2.1.jar
gwt-commons-logging-0.3.jar
gwt-commons-logging-service-0.3.jar
This is not a one time activity, so i would like to create a target or task in My build.xml for daily usage.
<replaceregexp file="file.txt" match="[^ ]*/" replace="" byline="true" flags="g"/>
Ant isn't well suited for tasks like this. It's probably much more simple to write a simple Ant Task in Java for that (or a small Java program; just create File objects and invoke getName() to get the last path element).
But if you have to: script and scriptdef are probably your friends (provided that your version of Ant is recent enough; the docs mention 1.6.3). You can call any Java method from these scripts. See the manual for examples.

Dynamic property names in ant

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 .

Reasons for using Ant Properties files over "Properties Tasks"

I'm currently working with some developers who like to set up Ant tasks that define environment specific variables rather than using properties files. It seems they prefer to do this because it's easier to type:
ant <environment task> dist
Than it is to type:
ant -propertyfile <environment property file> dist
So for example:
<project name="whatever" default="dist">
<target name="local">
<property name="webXml" value="WebContent/WEB-INF/web-local.xml"/>
</target>
<target name="remote">
<property name="webXml" value="WebContent/WEB-INF/web-remote.xml"/>
</target>
<target name="build">
<!-- build tasks here --->
</target>
<target name="dist" depends="build">
<war destfile="/dist/foo.war" webxml="${webXml}">
<!-- rest of war tasks here -->
</war>
</target>
I am finding it hard to convince them that properties files are they right way to go. I believe properties files are better because:
They provides more flexibility - if you need a new environment just add a new properties file
It's clearer what's going on - You have to know about this little "trick" to realize what they're accomplishing
Doesn't provide default values and the ability to use overrides - if they used property files they could provide defaults at the top of the project but have the ability to override them with a file
Script won't break if an environment task isn't supplied on command line
Of course all they hear is that they need to change their Ant script and have to type more on the command line.
Can you provide any additional arguments in favor of properties files over "property tasks"?
Properties tasks tightly couple the build file to environments. If your fellow developers are arguing that they "have to change their ant script" with your suggestions, why aren't they arguing about changing it every time they have to deploy to a new environment? :)
Perhaps you can convince them to allow both properties file and command-line configuration. I set up my Ant builds so that if a build.properties exists in the same directory as the build.xml, it reads it in. Otherwise it uses a set of default properties hard-coded into the build. This is very flexible.
<project name="example">
<property file="build.properties"/>
<property name="foo.property" value="foo"/>
<property name="bar.property" value="bar"/>
...
</project>
I don't provide a build.properties with the project (i.e. build.properties is not versioned in SCM). This way developers aren't forced to use the property file. I do provide a build.properties.example file that developers can reference.
Since Ant properties, once set, are immutable, the build file will use properties defined in this order:
Properties provided with -D or -propertyfile via the command line
Properties loaded from build.properties
Default properties within build.xml
Advantages of this approach:
The build file is smaller and therefore more maintainable, less bug-prone
Developers that just can't get away from setting properties at the command line can still use them.
Properties files can be used, but aren't required
The arguments you have are already pretty compelling. If those arguments haven't worked, then arguing isn't going to solve the problem. In fact, nothing is going to solve the problem. Don't assume that people are rational and will do the most practical thing. Their egos are involved.
Stop arguing. Even if you win, the resentment and irritation you create will not be worth it. Winning an argument can be worse than losing.
Make your case, then let it go. It's possible that after a while they will decide to switch to your way (because it actually is better). If that happens, they will act like it was their own idea. There will be no mention of your having proposed it.
On the other hand, they may never switch.
The only solution is to work towards a position of authority, where you can say how things are to be done.
The problem with the first solution (using ant property) is basically hardcoding.
It can be convenient when you start a project for yourself but quickly you have to remove that bad habit.
I'm using a property file close to what said robhruska except that I have committed the build.properties file directly. This way you have a default one.
In other hand, I understand I could add those default values in the build.xml. (I will probably try that in the next hours/days ;-) ).
Anyway, I really don't like the first approach and I would force those guys to follow the second one ...

Resources