Manipulating directories in Java Ant - java

I have an Ant xml file. In this file I want to set two properties based on the current working directory. The current working directory is always of the form /some/base/dir/SRC/sub/dir.
The first property must be set to the current working directory. The second property must be set to the part of the current working directory up to /SRC.
I can set the first property without any issue using the PWD environment variable , but I cannot figure out the second.
<property name="my.dir" value="${env.PWD}" />
<property name="src.dir" value="{what do I put here?}" />
I've heard this can be done with bash-style string manipulation (e.g. ${PWD%*/SRC}/SRC) using StringOps, but I cannot find any good examples.

One approach is to use the <pathconvert> task, perhaps like this:
<property name="my.dir" value="/some/base/dir/SRC/sub/dir"/>
<pathconvert property="src.dir">
<path path="${my.dir}"/>
<mapper type="regexp" from="^(.*)/SRC" to="\1" />
</pathconvert>
<echo message="src.dir=${src.dir}" />
Which gives:
[echo] src.dir=/some/base/dir
There are other mappers available which might work better for you than regexp.

Related

Adding environment variables in Ant build.properties

Is it possible to use $XXX_HOME style variables in a build.properties file?
I set path of variable in build.properties like this
ant.home=/opt/java/myanthome
I have a $ANT_HOME environment variable with the correct path. Can I use this environment variable to set my ant.home in build.properties? I tried to add this in build.xml
<property environment="env"/>
<property file="build.properties" />
and in the build.properties file:
ant.home=${env.ANT_HOME}
but this does not work,it says:
${env.ANT_HOME} does not exist
It is possible but there is no sense in doing it.
You can add a filter that pre-processes your property file. Consider the following property file:
ant.home=#ANT_HOME#
Then, you can filter it and load the file into properties, like this:
<filter token="ANT_HOME" value="${env.ANT_HOME}"/>
<copy file="build.properties" tofile="build.properties.filtered" filtering="true" />
<property file="build.properties.filtered" />
The filter task, in addition with filtering=true, will replace the #ANT_HOME# token by the value of ${env.ANT_HOME}.
But after having done all this, the question is, why filter the property file to begin with? You can just remove the ant.home property from your file and directly use ${env.ANT_HOME} where necessary.

Java Packager Tool : custom install location

I'm working around "Self-Contained Application" generation using Java Packager Tool. By default, the '.exe' bundle is installed under "C:\Program Files (x86)" but I would like install it to a custom location : "C:\MyApp" for example.
To generate my bundle, I'm using an Ant Task inside a Maven build :
<target xmlns:fx="javafx:com.sun.javafx.tools.ant">
<property name="jre.dir" value="${env.JAVA_HOME}/jre" />
<property name="version" value="0.0.3" />
<taskdef resource="com/sun/javafx/tools/ant/antlib.xml"
uri="javafx:com.sun.javafx.tools.ant" classpath="${env.JAVA_HOME}/lib/ant-javafx.jar" />
<echo message="// ----------------------------------- //" />
<echo message="// START JAVAPACKAGER ANT TASK //" />
<echo message="// ----------------------------------- //" />
<fx:deploy nativeBundles="exe" outdir="${basedir}/packager"
outfile="MyApp_${version}">
<fx:application name="MyApp" mainClass="com.myfirm.myapp.bootstrap.BootstrapMain">
<fx:argument>-bundlesDir=./bundles/</fx:argument>
</fx:application>
<fx:resources>
<fx:fileset dir="${project.basedir}/target"
includes="${project.name}-${project.version}-jar-with-dependencies.jar" />
<fx:fileset dir="${project.basedir}" includes="bundles/*.jar" />
</fx:resources>
<fx:info title="MyApp ${version}" vendor="MyFirm">
<fx:icon href="${project.basedir}/myapp.ico" kind="default" width="32" height="32" depth="8" />
</fx:info>
<fx:preferences install="true" shortcut="true" />
<fx:platform basedir="${jre.dir}"/>
</fx:deploy>
</target>
Has anybody work around this ? And could tell me more about how to configure more precisely the generated native bundle ?
Thanks by advance.
EDIT
Under Windows, I have found a way to do it : by editing file com\oracle\tools\packager\windows\template.iss in jar %JAVA_HOME%\lib\ant-javafx.jar. But this solution seems to be ugly and not portable ! So I'm now looking for a way to override it in my ant task...
For extra documentation, what Tib Us did was edit %JAVA_HOME%\lib\ant-javafx.jar. You can use 7-Zip (or others) to open that jar file and update it's contents.
In com\oracle\tools\packager\windows\template.iss, change this line:
DefaultDirName=APPLICATION_INSTALL_ROOT\APPLICATION_NAME
To:
DefaultDirName={pf}\APPLICATION_NAME
{pf} is a Inno Setup constant pointing to 32-bit or 64-bit Program Files folder. See Inno Setup Help.
If you'd like to install in Program Files, then it is helpful to change:
PrivilegesRequired=APPLICATION_INSTALL_PRIVILEGE
To:
PrivilegesRequired=admin
Also, if your program is going to be used by non-admin users and will be writing to its folder in Program Files, then you'll need some special folder permissions. Here is some background on permissions for an app running in Program Files.
You might also like to add this, to ensure that the new install location is used:
UsePreviousAppDir=No
This solution isn't ideal, but is better than nothing.
Getting the template from the jar file is fine—or download it here—but you don't need to edit it where it is.
Once you have that template, you can just use it as a drop-in resource. All the variables that look like SOME_VARIABLE, that is, upper case and which use underscores, will still be replaced by the javapackager.
This solution is much more portable because it doesn't involve editing the JDK; just include your template in package/windows/ as YourAppName.iss.
User Option -BinstalldirChooser=true

How Can I Call Another Ant Created Testing Suite From Any Target

<target name="Regression_Test" depends="displayEnvironment">
<property name="TestSuite" value="RegressioonTestSuite.xml"/>
<ant antfile="TestNG.xml" dir="${tools.loc}" target="runTestNG" inheritAll="true"/>
<!--<antcall target="buildAndTest" inheritAll="true"/>-->
</target>
In Above Code..
<property name="TestSuite" value="RegressioonTestSuite.xml"/>
Is Not Working, It does not pass to RegreessionTestSuite.xml
Created a file for regression testing Named as RegreessionTestSuite.xml
if i write
this code outside of target then it works but inside any target it won't
as per comments above, it would be helpful if you could post the error/exception you are getting.
In the meanwhile, a few tips to debug it could be:
call ant via the exec task (you can also do an echo of the command you are executing, to double check for typos etc.)
are the target you want to invoke in a different file? is this file 'imported' into your master build file?
Thank You for your support..
I am newer in Ant
Found Solution...Made a silly mistake
<ant antfile="TestNG.xml" dir="${tools.loc}" target="runTestNG" inheritAll="true">
<property name="TestSuite" value="RegressioonTestSuite.xml"/>
</ant>

Can I declare and initialize a variable in an Ant script?

In Ant, can I create a target that contains something like a variable that represents a path?
For example, something like the following pseudo target:
<target name="initPath">
Path = "${basedir}/../../myProject/Project/"
</target>
Where Path is my variable and is initializated to specific value.
How can I do this?
Ant build scripts are written in XML. To create a property has to be in XML style, so instead of this:
some_prop="some value"
It is this:
<property name="some_prop" value="some value"/>
Properties can contain periods, and I recommend using them as name separators:
<property name="some.prop" value="some value"/>
How do you declare a constant? Here:
<property name="some.prop" value="some value"/>
That's because once a property is set, it cannot be changed.
This way, you can do something like this:
<property file="${basedir}/build.properties"/>
<property name="some.prop" value="some value"/>
Let's say that the build.properties file contains this line:
some.prop="Some other value"/>
Now, when you run your Ant build file, the value of some.prop will be "Some other value", and the <property name="some.prop" value="some value"/> won't change it. I could even do this:
$ ant -Dsome.prop="A completely different value"
And this value of the some.prop property will override what I have in my build.properties file and what I have in my Ant build file.
This is a very nice feature. It allows me to set a default value that developers can override:
<property name="copy.verbose" value="false"/>
...
<copy todir="${copy.to.dir}"
verbose="${copy.verbose}">
<fileset dir="${copy.from.dir}"/>
</copy>
By default, when my copy task runs, it runs in non-verbose mode which is what I want. However, let's say I am having a few problems with my build, and I want to see exactly what is being copied, I could do this:
$ ant -Dcopy.verbose=true
And, now my copy tasks will show me all the files being copied.
A path is a way to declare something like $CLASSPATH or $PATH in the command line. You can predeclare a path with an id, and then use it later:
<javac destdir="${main.destdir}"
srcdir="${main.srcdir}">
<classpath>
<fileset dir="${lib.dir}">
<include name="*.jar"/>
</fileset>
</classpath>
</javac>
Here I'm adding a classpath. This is using <fileset/> to create a classpath based upon all of the jars in my ${lib.dir} directory.
I can also do this:
<path id="main.classpath">
<fileset dir="${lib.dir}">
<include name="*.jar"/>
</fileset>
</path>
<javac destdir="${main.destdir}"
srcdir="${main.srcdir}"
classpathref="main.classpath"/>
Here, I predeclare my main.classpath and then use that later in my <javac> task.
You should read up on Ant in the on line Ant Manual. There is a semi-decent introduction in the manual which might help clarify a few issues for you.
Here is how you can define a property in Ant script.
Unfortunately it is not a variable, since they are immutable. You can set a value to it, but you cannot change it during your script execution.
Here you can see an example of assigning value to a property.
Update.
You can use path task. For example:
<path id="combinedPath">
<path path="${toString:oldPath}"/>
<path path="my.jar"/>
</path>
<path id="reanamePath">
<path path="${toString:oldPath}"/>
</path>
If you change path in one target you can definitely access it in another one.
Ant has classpath-like support built-in.
In general you wouldn't use a property for this functionality.
Please consider reading the Ant documentation; this is Ant 101 and it'll be quicker in the long run if you spend some time with the docs and figuring out the Ant way of doing things.

ANT- Loading Multiple Java files from Several packages

I have several files scattered across several packages. I need to load the file one by one and perform operations using ANT but whenever I try, only one file gets loaded. For ex. I have 2 classes - com.abc.one.One and com.bcd.two.Two . The following script print both file name but only the first file as loaded file in both loop iterations
<target name="build" description="My Task">
<for param="file">
<path>
<fileset dir="C:\workspace\AntTest1" includes="**\*.java" />
</path>
<sequential>
<echo message="#{file}" />
<loadfile property="loadedFile" srcfile="#{file}" />
<echo message="${loadedFile}" />
</sequential>
</for>
</target>
I have tried searching the documentation but could not find the concise explanation on how to use loadfile task. I suspected that this might be because ant uses immutable string but could not get workaround. I tried to split the job by creating new target but that does not help me either. Any help is highly appreciated
Ant property can only be set once, and after it is set, it is immutable.
It has been some time since my Ant days, but perhaps the following solution can work: For each file, make an antcall call, with the file name as parameter. then, in the new target, load the file and perform your task. Notice that antcall can impact severely the runtime performance.

Categories

Resources