Apache Ant conditionally copy file from template and load properties - java

I have a property file (x.props) that contains properties required for an Ant build:
x.props:
prop1=something
prop2=somethingElse
set in build.xml:
<property file="x.props" />
The properties contained in x.props are then used in a path task:
<path id="project.class.path">
<pathelement location="${prop1}/important.jar"/>
<pathelement location="${prop2}/anotherImportant.jar"/>
</path>
Before compilation starts. I don't explicitly create these properties in build.xml
The x.props file can be different for each local user, but for server builds it doesn't change.
I created an x.props.template file to address the problem of users accidentally checking in or updating this file (but they need to be able to check it out). I want to be able to create an x.props file from the x.props.template (I set x.props as svn:ignore).
Users can save the template file as x.props and edit it and - theoretically, the server Ant build.xml can copy the template file to the server x.props if it doesn't exist.
But that's not happening. I tried using a target:
<target name="x-props-file" unless="prop1" description="create a
local.properties file if it doesn't exist">
<copy file="x.props.template" tofile="x.props" />
</target>
But it's called AFTER the path is set.
I tried creating the file as a condition:
<condition available="x.props">
<not>
<copy file="x.props.template" tofile="x.props" />
</not>
</condition>
But 'not' and 'condition' don't work with copy.
loadProperties will fail if the file isn't found - but it won't copy a file.
Ideally I'd like to be able to copy the new x.props right after the initial file load fails.
Is there any way around this?
ant version 1.1
java 7
Thanks

This would probably be simplest with ant-contrib's <if> task:
<if>
<not>
<available file="x.props" />
</not>
<then>
<copy file="x.props.template" tofile="x.props" />
</then>
</if>
Edit: I just rediscovered this answer that I gave years ago after a comment was added, and realized that there's a much better solution that doesn't rely on ant-contrib. It's probably way too late to be of much use to the original poster, but I figured I'd offer it up anyway in case it helps someone:
<property file="x.props" />
<property name="prop1" value="something" />
<property name="prop1" value="somethingElse" />
<path id="project.class.path">
<pathelement location="${prop1}/important.jar"/>
<pathelement location="${prop2}/anotherImportant.jar"/>
</path>
No need for an extra template file. Just attempt to load the property file first and set your defaults immediately after that, making use of Ant's inherent property immutability.
Conversely, if you really want to use a separate properties file to hold your default values, just do the same thing as above but replace the individual property assignments with another property file load:
<property file="x.props" />
<property file="default.props" />

Related

Placeholder for value/version/date replacement in xml using Ant build

I have more than 30 odx-d files (odx-d is just xml file with different extension).
All files have common tags:
<DOC-REVISION>
<REVISION-LABEL>01.02.03-04</REVISION-LABEL>
<STATE>RELEASE</STATE>
<DATE>2018-11-14T16:26:00+01:00</DATE>
</DOC-REVISION>
At every release I need to change these values in all files.
Note: Manipulation using Java is not possible as while build just making zip of all these files not using Java to manipulate these files.
Please suggest a way to have one file (any file type you suggest) where I can have these values and place holders for the tags in all these files.
Thanks.!
This is doable with the following steps:
replace the common tag values with placeholders e.g. #revision#,
#state#, #date#
copy each file to a temporary location
perform the replacements in the copied files using a <replace file="${dest.file}"> task with nested <replacefilter .../> elements
zip the transformed files in the temporary location
For example, using a template file "template.xml" like this:
<DOC-REVISION>
<REVISION-LABEL>#revision#</REVISION-LABEL>
<STATE>#state#</STATE>
<DATE>#date#</DATE>
</DOC-REVISION>
you can set the real values with this ant target (skipping the zip part):
<target name="test">
<property name="my.revision" value="01.02.03-04"/>
<property name="my.state" value="RELEASE"/>
<tstamp>
<format property="my.date" pattern="yyyy-MM-dd hh:mm z"/>
</tstamp>
<property name="template.file" value="./template.xml"/>
<property name="dest.file" value="./doc.odx"/>
<delete file="${dest.file}" quiet="true"/>
<copy toFile="${dest.file}" file="${template.file}"/>
<replace file="${dest.file}">
<replacefilter token="#revision#" value="${my.revision}"/>
<replacefilter token="#state#" value="${my.state}"/>
<replacefilter token="#date#" value="${my.date}"/>
</replace>
</target>
Solution for multiple files.
Replace values with placeholders #revision#, #state#, #date# and place into template folder.
Perform the copy operation with filterset from template to dest directory.
Example:
Template dir: 'fromDir', destination: 'toDir'
1) Template files:
<DOC-REVISION>
<REVISION-LABEL>#revision#</REVISION-LABEL>
<STATE>#state#</STATE>
<DATE>#date#</DATE>
</DOC-REVISION>
2) Declare properties and perform test target operation.
<!-- Properties -->
<property name="version" value="01.02.03-04" />
<property name="state" value="RELEASE" />
<tstamp>
<format property="now" pattern="yyyy-MM-dd'T'HH:mm:ss.SSSXXX"/>
</tstamp>
<!-- Target -->
<target name="test">
<copy todir="${toDir}">
<fileset dir="${fromDir}" />
<filterset>
<filter token="revision" value="${version}" />
<filter token="state" value="${state}" />
<filter token="date" value="${now}" />
</filterset>
</copy>
</target>
Thanks!

Access platform.properties variables from nbi ant script

is it possible to access from the ant script of the nbi (installer project) to variables defined in the platform.properties file, like the nbjdk.active which is setted when in a project the Java platform is changed?
The goal is from the ant script select one of the packaged jre (32 or 64) in function of this variable.
Thanks in advance.
Edit:
this is the build script fragment from when I try to access this variables:
<target name="-generate-bundles">
<for-each property="platform" list="${target.platforms}" separator=" ">
<condition property="bundle.extention.${platform}" value="exe">
<contains string="${platform}" substring="windows"/>
</condition>
<condition property="bundle.extention.${platform}" value="sh">
<or>
<contains string="${platform}" substring="linux"/>
<contains string="${platform}" substring="solaris"/>
</or>
</condition>
<condition property="bundle.extention.${platform}" value="zip">
<contains string="${platform}" substring="macosx"/>
</condition>
<set property="bundle.extention" source="bundle.extention.${platform}"/>
<create-bundle root="${output.dir}/registry-temp"
platform="${platform}"
target="${bundles.release.dir}/${bundle.files.prefix}-${platform}.${bundle.extention}">
<component uid="${main.product.uid}" version="1.0.0.0.0"/>
<!-- HERE I WANT TO CHECK THE VARIABLE AND SELECT ONE OF THE PACKED JRE -->
<!--<property name="nbi.bundled.jvm.file" value="D:\packed\jre1.8.0_65_32bits\jre.exe"/>-->
<property name="nbi.bundled.jvm.file" value="D:\packed\jre1.8.0_25_64bits\jre.exe"/>
</create-bundle>
<echo>************************</echo>
<echo>********* OS: ${platform}</echo>
<echo>********* Arch: ${os.arch}</echo>
<echo>********* JDK in NB: ${jdk.home}</echo>
<echo>********* JDK in platform.properties: HERE I TRY TO ACCESS VARIABLE</echo>
<echo>************************</echo>
<if property="bundle.extention" value="zip">
<antcall target="zip-to-tgz">
<param name="input.file" value="${bundles.release.dir}/${bundle.files.prefix}-${platform}.zip"/>
<param name="output.file" value="${bundles.release.dir}/${bundle.files.prefix}-${platform}.tgz"/>
</antcall>
<delete file="${bundles.release.dir}/${bundle.files.prefix}-${platform}.zip"/>
</if>
</for-each>
<echo>Installer(s) for [${target.platforms}] are available at ${bundles.release.dir}</echo>
</target>
and this is the variable in platform.properties file:
nbjdk.active=JDK_1.8.0_65-32bits
Here is the property file contents which are going to be accessed in the build script:
Below build script example shows how to access property abc which is from test.properties file.
All you need is to load the property file before accessing it as shown in the script using, of course, change the property file path as per your environment.
<property file="D:/Temp/test.properties"/>
Then use ${abc} whereever its value is needed as shown in the echo task below.
test.properties contents
abc=123
def=234
build.xml
<project name="imported" basedir="." default="test">
<property file="D:/Temp/test.properties"/>
<target name="test" description="check if the property can be retrieved from file">
<echo message="Property abc's value from file is ${abc}"/>
</target>
</project>
Output
test:
[echo] Property abc's value from file is 123
BUILD SUCCESSFUL
Total time: 0 seconds
[Finished in 4.7s]
Hope this is helpful.

How can I prevent Eclipse from auto-rebuilding when I edit certain files?

I'm developing a Java application using Eclipse Luna. I began looking into Ant scripts earlier today to develop a way of producing version numbers for the software as it changes. I'm pretty happy with it so far but the one remaining issue I seem to have is that I have an Ant script build.xml which modifies the build number of a property file build_info.properties whenever Eclipse recompiles the source code.
However, I've set Eclipse to rebuild automatically which means that any changes made to what it considers as the project's source files invokes this recompilation process, and so when build_info.properties is modified, it causes everything to be recompiled again in a feedback loop.
What I'm wondering is if there's a way I can prevent this from happening while still having auto-rebuild enabled such that Eclipse won't recompile everything every time that build_info.properties changes?
I've looked at this similar question but Robert's answer is not applicable to my situation and Javi's answer doesn't appear to work for me (I tried putting build_info.properties in its own source folder and setting the folder's exclusion pattern to **).
The relevant parts of build.xml are given below:
<target name="compile" depends="updateRevision">
<echo>Compiling...</echo>
<antcall target="build">
</antcall>
</target>
<target name="updateRevision" if="git.present">
<exec executable="git" outputproperty="git.hash" failifexecutionfails="true" errorproperty="">
<arg value="rev-parse" />
<arg value="HEAD" />
</exec>
<propertyfile file="${propertyfile.name}">
<entry key="build.revision.number" type="string" operation="=" value="${git.hash}" />
</propertyfile>
</target>
<target name="build" depends="updateRevision">
<propertyfile file="${propertyfile.name}">
<entry key="build.build.number" type="int" operation="+" value="1" />
</propertyfile>
</target>

unable to read system properties inside jar which is in classpath of another java project

My project has a jar in classpath with some utilities in it. When I run the program using ant on Red Hat linux, it's unable to read the system properties using System.getProperty(key), but it works perfectly fine when ran on Ubuntu.
Any suggestion to why this might be happening is appreciated.
ant target
<target name="test">
<property environment="env"/>
<echo message="PATH_ROOT set => ${env.PATH_ROOT}" />
<echo message="CUSTOM_REPORT_PATH set => ${env.CUSTOM_REPORT_PATH}" />
<testng classpathref="compile.classpath" haltOnfailure="false" outputDir="${testng.output.dir}/xxx">
<sysproperty key="PATH_ROOT" value="${env.PATH_ROOT}"/>
<sysproperty key="CUSTOM_REPORT_PATH" value="${env.CUSTOM_REPORT_PATH}"/>
<xmlfileset dir="src/com/xxx" includes="suite.xml" />
</testng>
</target>
================
Guys it was a silly mistake. The framework was not executing the file which had the statements to fetch system variables as the listener was missing in testng suite which is a must for testng to invoke that

Ant resource exists check

I have problem testing file existence with ant. I want to check if files exist in target test, and if not, I want download files in target download. But the download target will be executed always (if files exist or not). Can anybody show what is wrong?
<!-- Test lib files if exist -->
<target name="test">
<condition property="is.resource.exists" value="true" else="false">
<and>
<resourceexists>
<file file="${lib}/jdom-2.0.5.jar" />
</resourceexists>
<resourceexists>
<file file="${lib}/miglayout-4.0-swing.jar" />
</resourceexists>
</and>
</condition>
</target>
<!-- Download lib files if not exist -->
<target name="download" if="is.resource.exists" depends="test">
<exec dir="${lib}" executable="${lib}/get-libs.sh" />
</target>
A <target> with an if attribute will execute if the property in the if attribute exists. Similarly, a <target> with an unless attribute will execute if the property in the unless attribute doesn't exist. It doesn't matter what the value of the property is: true, false, kumquat, or whatever.
Replace the if="is.resource.exists" with unless="is.resource.exists" and you should be good.

Categories