updating relative path of jar while working on different OS - ant

I would like to replace path of an existing jar based on OS .
Right now i am maintaning a text file called "build.start.properties" with all libraries some ting 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
And loading them to classptah using below target
<loadfile property="jars.list.property" srcfile="mybuild/build.start.properties">
<filterchain>
<expandproperties />
<striplinecomments>
<comment value="#" />
</striplinecomments>
<tokenfilter>
<ignoreblank />
</tokenfilter>
<prefixlines prefix="," />
<striplinebreaks />
</filterchain>
</loadfile>
<filelist id="build.libs" dir="" files="${jars.list.property}" />
<pathconvert targetos="unix" property="build_unix.libs" refid="build.libs">
<map from="C:" to="${unix.xenv}" />
<map from="" to="${unix.xenv}" />
</pathconvert>
<pathconvert targetos="windows" property="build_windows.libs" refid="build.libs">
<map from="C:" to="${windows.xenv}" />
<map from="" to="${windows.xenv}" />
</pathconvert>
<path id="build.classpath.id">
<pathelement path="${build_windows.libs}" />
<pathelement path="${build_unix.libs}" />
</path>
<echo message="Build Libraries classpath: ${toString:build.classpath.id}" />
</target>
from the above target build.classpath.id looks like
/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
When i work on unix I have to pic only jar names from file "build.start.properties" and update path like this
/WebContent/WEB_INF/lib/gwt-servlet.jar:/WebContent/WEB_INF/lib/gwt-user.jar:/WebContent/WEB_INF/lib/gwt-dev.jar:/WebContent/WEB_INF/lib/gwt-soyc-vis.jar:/WebContent/WEB_INF/lib/log4j-1.2.15.jar:/WebContent/WEB_INF/lib/gwt-log-3.0.3.jar:/WebContent/WEB_INF/lib/gwt-math-2.1.jar:/WebContent/WEB_INF/lib/gwt-math-server-2.1.jar:/WebContent/WEB_INF/lib/gwt-commons-logging-0.3.jar:/WebContent/WEB_INF/lib/gwt-commons-logging-service-0.3.jar

Use the conditions
<condition property="isWindows">
<os family="windows" />
</condition>
<condition property="isUnix">
<os family="unix" />
</condition>
On the targets then u can use
<target name="path_if_unix" if="isUnix">
<map from="C:" to="${unix.xenv}" />
<map from="" to="${unix.xenv}" />
</target>

Related

jenkins build configuration- packaging EAR issue

I have the build configuration set up for jenkins and while packaging EAR it is neglecting an xml file while it builds. I want to make sure that file gets updated via build configuration .
''''''EAR Packager file
<property name="librariesFolderPath" value="${basedir}/../libs" />
<taskdef resource="net/sf/antcontrib/antcontrib.properties">
<classpath>
<pathelement location="${librariesFolderPath}/ant-contrib.jar" />
</classpath>
</taskdef>
<property environment="env" />
<condition property="partialWsPath" value="**/${TO_BUILD}/**" else="**">
<and>
<isset property="TO_BUILD" />
<not>
<equals arg1="${TO_BUILD}" arg2="" trim="true" />
</not>
</and>
</condition>
<condition property="lurch.properties.file" value="${project.properties.file}" else="lurchproject.properties">
<and>
<isset property="project.properties.file" />
<not>
<equals arg1="${project.properties.file}" arg2="" trim="true" />
</not>
</and>
</condition>
<pathconvert property="project.properties.path">
<fileset dir="${env.WORKSPACE}" includes="${partialWsPath}/${lurch.properties.file}" />
</pathconvert>
<property file="${project.properties.path}" />
<propertyregex property="studio.buildnumber" input="${studio.version}" regexp="(.*)[a-zA-Z]$" select="\1" defaultvalue="${studio.version}" />
<property file="${basedir}/../config/builderstructure.properties" />
<property file="${basedir}/barpackager.properties" />
<property file="${runtime.properties.file}" />
<property name="lurch.customized.folder.path" value="${basedir}/../../customized" />
<!-- Retriving deploy-project name -->
<propertyregex property="deploy.project.name" input="${deploy.project}" regexp="([^\\/]*)[\\/]?$" select="\1" />
<!-- Retriving the list of libraries that mustn't be in the ear -->
<propertyregex property="targetj2ee" input="${target.j2ee}" regexp=" " replace="_" global="true" />
<propertycopy property="libs2cutoff" from="libs2cutoff.${targetj2ee}" />
<!-- =================================
target: default
================================= -->
<target name="earsPackagingCompleted"
depends="init,evaluateConditions,createDeployJar,generateManifest,createEJB,createWAR,createEar,customizeEar"
description="Calls all the targets needd to generate the ear" />
<!-- =================================
target: init
================================= -->
<target name="init" description="Compute the build order">
<delete dir="${output.ears}" includeemptydirs="true" />
<mkdir dir="${output.ears.tmp.lib}" />
<mkdir dir="${output.ears.tmp.war}/META-INF" />
<mkdir dir="${output.ears.tmp.ejb}/META-INF" />
</target>
<!-- =================================
target: evaluateConditions
================================= -->
<target name="evaluateConditions" depends="" description="Evaluates conditions rekated to ear creation">
<condition property="appl.srv.project.folder"
value="${runtime.projects.to.build}/${deploy.project.name}/${deploy.appl.srv.folder}/${target.j2ee}">
<!-- else="${eclipse.plugins}/${appl.srv.studio.folder}/${target.j2ee}" -->
<and>
<isset property="deploy.appl.srv.folder" />
<not>
<equals arg1="${deploy.appl.srv.folder}" arg2="" trim="true" />
</not>
<isset property="target.j2ee" />
<not>
<equals arg1="${target.j2ee}" arg2="" trim="true" />
</not>
<available file="${runtime.projects.to.build}/${deploy.project.name}/${deploy.appl.srv.folder}" type="dir" />
<available file="${runtime.projects.to.build}/${deploy.project.name}/${deploy.appl.srv.folder}/${target.j2ee}" type="dir" />
<resourcecount when="greater" count="0">
<fileset dir="${runtime.projects.to.build}/${deploy.project.name}/${deploy.appl.srv.folder}/${target.j2ee}" />
</resourcecount>
</and>
</condition>
<echo message="appl.srv.project.folder: ${appl.srv.project.folder}" level="verbose" />
</target>
<!-- =================================
target: createDeployJar
================================= -->
<target name="createDeployJar">
<!-- Add the DeployInfo.xml file and replace the token with the actual J2EE target server -->
<copy file="${eclipse.plugins}/${appl.srv.studio.folder}/.misc/config/DeployInfo.xml"
todir="${runtime.projects.to.build}/${deploy.project.name}/bin/config"
overwrite="true" />
<replace file="${runtime.projects.to.build}/${deploy.project.name}/bin/config/DeployInfo.xml" token="%TargetJ2ee%" value="${target.j2ee}" />
<echo message="[DD] earpackager createDeployJar $${output.jars}/$${deploy.project.name}.jar: '${output.jars}/${deploy.project.name}.jar'."/>
<echo message="[DD] earpackager createDeployJar $${runtime.projects.to.build}/$${deploy.project.name}/bin: '${runtime.projects.to.build}/${deploy.project.name}/bin'."/>
<jar destfile="${output.jars}/${deploy.project.name}.jar" keepcompression="true">
<manifest>
<attribute name="Created-By" value="Finantix Studio ${studio.version}" />
<attribute name="Build-Jdk" value="${java.version} ${java.vendor}" />
<attribute name="Built-By" value="L.U.R.Ch - Fx automated build system - ${builder.full.version}" />
<attribute name="Implementation-Title" value="${deploy.project.name}" />
<attribute name="Implementation-Version" value="${project.full.version}" />
<attribute name="Implementation-Vendor" value="${implementation.vendor}" />
</manifest>
<fileset dir="${runtime.projects.to.build}/${deploy.project.name}/bin" />
</jar>
</target>
<!-- =================================
target: generateManifest
================================= -->
<target name="generateManifest" depends="cleanupJarsForEar" description="Generates the manifest files for the war and ejb files">
<propertyregex property="classpath.runtime.patches" input="${deploy.libraries}" regexp="," replace=" lib/" global="true" />
<propertyregex property="classpath.runtime.patches" input="${classpath.runtime.patches}" regexp="(.*)" select="lib/\1" override="true" />
<echo message="classpath.runtime.patches: ${classpath.runtime.patches}" level="verbose" />
<pathconvert property="classpath.other.runtime.patches" pathsep=" ">
<path>
<fileset dir="${project.libraries.folder.path}/${4Ear.patches}"
includes="${selectable.required.libraries}"
excludes="${selectable.deploy.libraries}" />
<fileset dir="${project.libraries.folder.path}/${4EarAndCompiling.patches}"
includes="${selectable.required.libraries}"
excludes="${selectable.deploy.libraries}" />
<fileset dir="${project.libraries.folder.path}/${4Ear.lib3p}"
includes="${selectable.required.libraries}"
excludes="${selectable.deploy.libraries}" />
<fileset dir="${project.libraries.folder.path}/${4EarAndCompiling.lib3p}"
includes="${selectable.required.libraries}"
excludes="${selectable.deploy.libraries}" />
<fileset dir="${project.libraries.folder.path}/${4Ear.libJavaPrj}"
includes="${selectable.required.libraries}"
excludes="${selectable.deploy.libraries}" />
<fileset dir="${project.libraries.folder.path}/${4EarAndCompiling.libJavaPrj}"
includes="${selectable.required.libraries}"
excludes="${selectable.deploy.libraries}" />
</path>
<chainedmapper>
<mapper type="flatten" />
<globmapper from="*" to="lib/*" />
</chainedmapper>
</pathconvert>
<echo message="classpath.other.runtime.patches: ${classpath.other.runtime.patches}" level="verbose" />
<pathconvert property="classpath.generated.bars" pathsep=" ">
<path>
<fileset dir="${output.bars}" />
</path>
<chainedmapper>
<mapper type="flatten" />
<globmapper from="*" to="lib/*" />
</chainedmapper>
</pathconvert>
<echo message="classpath.generated.bars: ${classpath.generated.bars}" level="verbose" />
<pathconvert property="classpath.generated.jars" pathsep=" ">
<path>
<fileset dir="${output.jars}" includes="**/*.*" />
</path>
<chainedmapper>
<mapper type="flatten" />
<globmapper from="*" to="lib/*" />
</chainedmapper>
</pathconvert>
<echo message="classpath.generated.jars: ${classpath.generated.jars}" level="verbose" />
<pathconvert property="classpath.not.generated.libs.and.bars" pathsep=" ">
<path>
<fileset dir="${input.ftp.bars}" includes="${required.bars}" excludes="${libs.and.bars.to.exclude}" />
</path>
<chainedmapper>
<mapper type="flatten" />
<globmapper from="*" to="lib/*" />
</chainedmapper>
</pathconvert>
<echo message="classpath.not.generated.libs.and.bars: ${classpath.not.generated.libs.and.bars}" level="verbose" />
<pathconvert property="classpath.studio.bars" pathsep=" ">
<path>
<fileset dir="${eclipse.plugins}" includes="${bars.from.fs.plugins}" excludes="${libs2cutoff}" />
</path>
<chainedmapper>
<mapper type="flatten" />
<globmapper from="*" to="lib/*" />
</chainedmapper>
</pathconvert>
<echo message="classpath.studio.bars: ${classpath.studio.bars}" level="verbose" />
<pathconvert property="classpath.fs.plugins.4.ear" pathsep=" ">
<path>
<fileset dir="${eclipse.plugins}" includes="${fs.plugins.4.ear}" excludes="${libs2cutoff},${selectable.required.libraries}" />
</path>
<chainedmapper>
<mapper type="flatten" />
<globmapper from="*" to="lib/*" />
</chainedmapper>
</pathconvert>
<echo message="classpath.fs.plugins.4.ear: ${classpath.fs.plugins.4.ear}" level="verbose" />
<!--property name="EARClasspath" value="${classpath.runtime.patches} ${classpath.generated.jars} ${classpath.generated.bars} ${classpath.not.generated.libs.and.bars} ${classpath.other.runtime.patches} ${classpath.studio.bars} ${classpath.studio.plugins} ${classpath.3rd.parties.libs}" /-->
<property name="EARClasspath"
value="${classpath.runtime.patches} ${classpath.generated.jars} ${classpath.generated.bars} ${classpath.not.generated.libs.and.bars} ${classpath.other.runtime.patches} ${classpath.studio.bars} ${classpath.fs.plugins.4.ear}" />
<propertyregex property="EARClasspath" input="${EARClasspath}" regexp="\s+" replace=" " global="true" override="true" />
<echo message="EARClasspath: ${EARClasspath}" level="verbose" />
<manifest file="${output.ears.tmp.war}/META-INF/MANIFEST.MF">
<attribute name="Created-By" value="Finantix Studio ${studio.version}" />
<attribute name="Build-Jdk" value="${java.version} ${java.vendor}" />
<attribute name="Built-By" value="L.U.R.Ch - Fx automated build system - ${builder.full.version}" />
<attribute name="Implementation-Version" value="${project.full.version}" />
<attribute name="Implementation-Vendor" value="${implementation.vendor}" />
<attribute name="Class-Path" value="${EARClasspath}" />
</manifest>
<copy file="${output.ears.tmp.war}/META-INF/MANIFEST.MF" tofile="${output.ears.tmp.ejb}/META-INF/MANIFEST.MF" />
</target>
<!-- =================================
target: cleanupJarsForEar
================================= -->
<target name="cleanupJarsForEar" depends="cleanupBarsForEar" description="Remove java files from the archives to store in the ear.">
<fileset dir="${output.ears.tmp.lib}" id="jar.files.to.update.id">
<include name="*.jar" />
<exclude name="*_bar.jar" />
</fileset>
<echo level="info" message="********* Removing source code from jar files *******" />
<property name="jar.files.to.update" refid="jar.files.to.update.id" />
<for list="${jar.files.to.update}" delimiter=";" param="jar.file">
<sequential>
<echo message="=========================================" />
<echo message=" Updating ${jar.counter} out of ${number.of.jars.to.update} jar files ..." />
<exec executable="7za">
<arg value="d" />
<arg value="-tzip" />
<arg value="${output.ears.tmp.lib}/#{jar.file}" />
<arg value="*.java" />
<arg value="-r" />
</exec>
<math result="jar.counter" operation="+" operand1="${jar.counter}" operand2="1" datatype="int" />
</sequential>
</for>
</target>
<!-- =================================
target: cleanupBarsForEar
================================= -->
<target name="cleanupBarsForEar" depends="moveLibraries" description="Remove useless files from the archives to store in the ear.">
<resourcecount property="number.of.jars.to.update">
<fileset dir="${output.ears.tmp.lib}">
<include name="*.jar" />
</fileset>
</resourcecount>
<echo level="info" message="********* Removing source code, java and dat files from ${number.of.jars.to.update} bar files *******" />
<var name="jar.counter" value="1" />
<fileset dir="${output.ears.tmp.lib}" id="bar.files.to.update.id">
<include name="*_bar.jar" />
</fileset>
<property name="bar.files.to.update" refid="bar.files.to.update.id" />
<for list="${bar.files.to.update}" delimiter=";" param="bar.file">
<sequential>
<echo message="=========================================" />
<echo message=" Updating ${jar.counter} out of ${number.of.jars.to.update} bar files ..." />
<exec executable="7za">
<arg value="d" />
<arg value="-tzip" />
<arg value="${output.ears.tmp.lib}/#{bar.file}" />
<arg value="META-INF/*.dat" />
<arg value="META-INF/.bar" />
<arg value="src" />
<arg value="*.java" />
<arg value="-r" />
</exec>
<math result="jar.counter" operation="+" operand1="${jar.counter}" operand2="1" datatype="int" />
</sequential>
</for>
</target>
<!-- =================================
target: moveLibraries
================================= -->
<target name="moveLibraries" description="Moves files into the lib folder in the temporary ear folder">
<pathconvert property="libs.and.bars.to.exclude" pathsep=",">
<path>
<fileset dir="${output.bars}" />
<fileset dir="${output.jars}" />
</path>
<chainedmapper>
<mapper type="flatten" />
<regexpmapper from="(.*)" to="**/\1" />
</chainedmapper>
</pathconvert>
<propertyregex property="selectable.deploy.libraries" input="${deploy.libraries}" regexp="," replace=",**/" global="true" />
<propertyregex property="selectable.deploy.libraries" input="${selectable.deploy.libraries}" regexp="(.*)" select="**/\1" override="true" />
<propertyregex property="selectable.required.libraries" input="${required.libraries}" regexp="," replace=",**/" global="true" />
<propertyregex property="selectable.required.libraries"
input="${selectable.required.libraries}"
regexp="(.*)"
select="**/\1"
override="true" />
<copy todir="${output.ears.tmp.lib}" flatten="true" failonerror="true">
<fileset dir="${project.libraries.folder.path}/${4Ear.patches}"
includes="${selectable.deploy.libraries},${selectable.required.libraries}" />
<fileset dir="${project.libraries.folder.path}/${4EarAndCompiling.patches}"
includes="${selectable.deploy.libraries},${selectable.required.libraries}" />
<fileset dir="${project.libraries.folder.path}/${4Ear.lib3p}"
includes="${selectable.deploy.libraries},${selectable.required.libraries}" />
<fileset dir="${project.libraries.folder.path}/${4EarAndCompiling.lib3p}"
includes="${selectable.deploy.libraries},${selectable.required.libraries}" />
<fileset dir="${project.libraries.folder.path}/${4Ear.libJavaPrj}"
includes="${selectable.deploy.libraries},${selectable.required.libraries}" />
<fileset dir="${project.libraries.folder.path}/${4EarAndCompiling.libJavaPrj}"
includes="${selectable.deploy.libraries},${selectable.required.libraries}" />
<fileset dir="${output.bars}" />
<fileset dir="${output.jars}" />
<fileset dir="${input.ftp.bars}" includes="${required.bars}" excludes="${libs.and.bars.to.exclude}" />
<fileset dir="${eclipse.plugins}" includes="${bars.from.fs.plugins}" excludes="${libs2cutoff}" />
<fileset dir="${eclipse.plugins}" includes="${fs.plugins.4.ear}" excludes="${libs2cutoff},${selectable.required.libraries}" />
</copy>
</target>
<!-- =================================
target: createEJB
================================= -->
<target name="createEJB">
<copy todir="${output.ears.tmp.ejb}" overwrite="false">
<fileset dir="${eclipse.plugins}/${appl.srv.studio.folder}/${target.j2ee}/EJB" />
</copy>
<antcall target="updateWithCustomFiles">
<param name="destination.folder" value="${output.ears.tmp.ejb}" />
<param name="source.folder" value="${appl.srv.project.folder}/EJB" />
<param name="overwrite" value="true" />
</antcall>
<jar destfile="${output.ears.tmp}/${ejb.name}.jar" basedir="${output.ears.tmp.ejb}" manifest="${output.ears.tmp.ejb}/META-INF/MANIFEST.MF" />
<delete dir="${output.ears.tmp.ejb}" includeEmptyDirs="true" />
</target>
<!-- =================================
target: createWAR
================================= -->
<target name="createWAR">
<copy todir="${output.ears.tmp.war}" overwrite="true">
<fileset dir="${web.project.folder.path}">
<exclude name="work/" />
<exclude name="**/.classpath" />
<exclude name="**/.project" />
</fileset>
</copy>
<copy todir="${output.ears.tmp.war}" overwrite="false">
<fileset dir="${eclipse.plugins}/${appl.srv.studio.folder}/${target.j2ee}/WAR" />
</copy>
<antcall target="updateWithCustomFiles">
<param name="destination.folder" value="${output.ears.tmp.war}" />
<param name="source.folder" value="${appl.srv.project.folder}/WAR" />
<param name="overwrite" value="true" />
</antcall>
<for list="${web.project.version.files}" delimiter="," param="web.project.version.file">
<sequential>
<replace file="${output.ears.tmp.war}/#{web.project.version.file}"
token="${web.project.version.token}"
value="${project.full.version}" />
</sequential>
</for>
<antcall target="evaluateWebXmlConditions">
<param name="web.xml.path" value="${output.ears.tmp.war}/WEB-INF/web.xml" />
</antcall>
<war destfile="${output.ears.tmp}/${war.name}.war"
basedir="${output.ears.tmp.war}"
manifest="${output.ears.tmp.war}/META-INF/MANIFEST.MF"
webxml="${output.ears.tmp.war}/WEB-INF/web.xml" />
<delete dir="${output.ears.tmp.war}" includeEmptyDirs="true" />
</target>
<!-- =================================
target: evaluateWebXmlConditions
================================= -->
<target name="evaluateWebXmlConditions">
<loadfile property="web.content" srcFile="${web.xml.path}">
<filterchain>
<tokenfilter>
<filetokenizer />
<replaceregex pattern="<!--.*?-->" flags="gs" replace="" />
</tokenfilter>
</filterchain>
</loadfile>
<condition property="workManagerIsToAdd">
<not>
<contains string="${web.content}" substring="<res-ref-name>wm/WorkManager</res-ref-name>" />
</not>
</condition>
<condition property="ejbTimerIsToAdd">
<not>
<contains string="${web.content}" substring="<ejb-ref-name>ejb/EJBTimerServiceExecutorHome</ejb-ref-name>" />
</not>
</condition>
<antcall target="addWorkManager" />
<antcall target="addEjbTimer" />
</target>
<!-- =================================
target: addWorkManager
================================= -->
<target name="addWorkManager" if="workManagerIsToAdd">
<property name="tab" value=" " />
<replaceregexp file="${web.xml.path}"
match="</servlet-mapping>([^\w>]*)<resource-ref>"
replace="</servlet-mapping>${line.separator}${tab}<resource-ref>${line.separator}${tab}${tab}<!--WorkManager-->${line.separator}${tab}${tab}<description>Required for concurrency support</description>${line.separator}${tab}${tab}<res-ref-name>wm/WorkManager</res-ref-name>${line.separator}${tab}${tab}<res-type>commonj\.work\.WorkManager</res-type>${line.separator}${tab}${tab}<res-auth>Container</res-auth>${line.separator}${tab}${tab}<res-sharing-scope>Shareable</res-sharing-scope>${line.separator}${tab}</resource-ref>${line.separator}${tab}<resource-ref>"
flags="s" />
</target>
<!-- =================================
target: addEjbTimer
================================= -->
<target name="addEjbTimer" if="ejbTimerIsToAdd">
<property name="tab" value=" " />
<replaceregexp file="${web.xml.path}"
match="</web-app>"
replace="${tab}<!--EJB Timer reference -->${line.separator}${tab}<ejb-ref>${line.separator}${tab}${tab}<ejb-ref-name>ejb/EJBTimerServiceExecutorHome</ejb-ref-name>${line.separator}${tab}${tab}<ejb-ref-type>Session</ejb-ref-type>${line.separator}${tab}${tab}<home>com.finantix.foundation.integration.ejbtimer.EJBTimerServiceExecutorHome</home>${line.separator}${tab}${tab}<remote>com.finantix.foundation.integration.ejbtimer.EJBTimerServiceExecutor</remote>${line.separator}${tab}${tab}<ejb-link>EJBTimerServiceExecutor</ejb-link>${line.separator}${tab}</ejb-ref>${line.separator}</web-app>"
flags="s" />
</target>
<!-- =================================
target: createEar
================================= -->
<target name="createEar">
<copy todir="${output.ears.tmp}" overwrite="true">
<fileset dir="${eclipse.plugins}/${appl.srv.studio.folder}/${target.j2ee}/EAR" />
</copy>
<antcall target="updateWithCustomFiles">
<param name="destination.folder" value="${output.ears.tmp}" />
<param name="source.folder" value="${appl.srv.project.folder}/EAR" />
<param name="overwrite" value="true" />
</antcall>
<replace file="${output.ears.tmp}/META-INF/application.xml" token="%ContextRoot%" value="${context.root}" />
<replace file="${output.ears.tmp}/META-INF/application.xml" token="%WARName%" value="${war.name}" />
<replace file="${output.ears.tmp}/META-INF/application.xml" token="%EJBName%" value="${ejb.name}" />
<jar destfile="${output.ears}/${ear.name}.ear" basedir="${output.ears.tmp}">
<manifest>
<attribute name="Created-By" value="Finantix Studio ${studio.version}" />
<attribute name="Build-Jdk" value="${java.version} ${java.vendor}" />
<attribute name="Built-By" value="L.U.R.Ch - Fx automated build system - ${builder.full.version}" />
<attribute name="Implementation-Version" value="${project.full.version}" />
<attribute name="Implementation-Vendor" value="${implementation.vendor}" />
</manifest>
</jar>
<delete dir="${output.ears.tmp}" includeEmptyDirs="true" />
</target>
<!-- =================================
target: updateWithCustomFiles
================================= -->
<target name="updateWithCustomFiles" depends="evaluateCopyConditions" if="copy.is.executable">
<copy todir="${destination.folder}" overwrite="${overwrite}">
<fileset dir="${source.folder}" />
</copy>
</target>
<!-- =================================
target: evaluateCopyConditions
================================= -->
<target name="evaluateCopyConditions">
<condition property="copy.is.executable">
<and>
<isset property="appl.srv.project.folder" />
<available file="${source.folder}" type="dir" />
</and>
</condition>
</target>
<!-- =================================
target: customizeEar
================================= -->
<target name="customizeEar" if="custom.script.path" depends="checkForCustomScript">
<propertyregex property="workspaces.folder.path" input="${project.properties.path}" regexp="(.*?)/[^\\/]*$" select="\1" />
<ant antfile="${custom.script.path}" inheritAll="false">
<property name="ant-contrib.jar.path" value="${librariesFolderPath}/ant-contrib.jar" />
<property name="lurch.libraries.folder.path" value="${librariesFolderPath}" />
<property name="output.ears.folder.path" value="${output.ears}" />
<property name="ear.name" value="${ear.name}" />
<property name="deploy.project.name" value="${deploy.project.name}" />
<property name="studio.version" value="${studio.version}" />
<property name="java.version" value="${java.version}" />
<property name="java.vendor" value="${java.vendor}" />
<property name="builder.full.version" value="${builder.full.version}" />
<property name="project.full.version" value="${project.full.version}" />
<property name="workspaces.folder.path" value="${workspaces.folder.path}" />
<property name="output.bars.folder.path" value="${output.bars}" />
<property name="output.jars.folder.path" value="${output.jars}" />
<property name="output.ddls.folder.path" value="${output.ddls}" />
<property name="output.processes.folder.path" value="${output.processes}" />
<property name="output.translations.folder.path" value="${output.translations}" />
<property name="manifest.properties.file" value="${manifest.properties.file}" />
<propertyset>
<propertyref prefix="${custom.ear.properties.prefix}" />
</propertyset>
</ant>
</target>
<!-- =================================
target: checkForCustomScript
================================= -->
<target name="checkForCustomScript">
<condition property="custom.script.path" value="${lurch.customized.folder.path}/${project.phase.id}/${custom.ear.script}">
<and>
<isset property="project.phase.id" />
<not>
<equals arg1="project.phase.id" arg2="" trim="true" />
</not>
<available file="${lurch.customized.folder.path}/${project.phase.id}/${custom.ear.script}" type="file" />
</and>
</condition>
</target>
'''''''''''''''''''
The file name is FxCONF.xml which needs to be packaged in Deploy JAR.
Please advise how can i change the above code to make sure i include this file while pacaging.
Java is not my specialty, but I believe that to move and use the file (FxConf.xml) you need to add this copy action.
If I understand what you need I think the way is here:
How do I create an EAR file with an ant build including certain files?
Here can be another reference.
https://gist.github.com/mudzot/865511
Are you using ant?
I hope to be more helping than hinder. :)

No Unit Test Statistics Displayed in Sonar even when Test Coverage is displayed

We are using ant for our build process. We wanted to get the test coverage for our project. So we integrated jacoco with sonar to perform the test coverage.
The test Coverage is displayed correctly but the Unit Test Statistics are not displayed at all.
After searching in various forums we saw that it might be related with the sonar.tests/sonar.binaries/sonar.junit.reportsPath configuration.
But even after making all these changes we are still not able to see the Unit Test Statistics in Sonar.
We are using,
Sonar Qube 4.5.2
Sonar Ant 2.2
Jacoco 0.7.2.201409121644
Please Assist.
-build.xml
<taskdef uri="antlib:org.jacoco.ant" resource="org/jacoco/ant/antlib.xml" >
<classpath path="${jacoco_path}/lib/jacocoant.jar" />
</taskdef>
<target name="testCoverage" depends = "triv.build.all" description="Run unit tests and code coverage reporting">
<jacoco:coverage destfile="${CB_dirsrc}/reports/jacoco.exec" xmlns:jacoco="antlib:org.jacoco.ant">
<junit haltonfailure="no" fork="true" printsummary="true" failureproperty="junitsFailed" errorProperty="junitsFailed" forkmode ="once">
<jvmarg value="-XX:MaxPermSize=512m"/>
<jvmarg value="-Xmx1024m"/>
<jvmarg value="-Xms1024m"/>
<classpath>
<path refid="test.classpath"/>
<path refid="core.classpath"/>
<pathelement path="${test.classes.dir}/classes"/>
</classpath>
<!--<formatter type="plain" usefile="false" />-->
<formatter type="xml"/>
<batchtest fork="yes" todir="${CB_dirsrc}/reports/junit">
<fileset dir="${test.src.dir}">
<!--<include name="**/*Test*.java"/>-->
<include name="**/*BasicTests.java"/>
<!--<exclude name="**/*BasicTests.java"/>-->
<exclude name="**/*TICPTestHook.java"/>
<exclude name="**/*TRIVTestCase.java"/>
<exclude name="**/*TestContext.java"/>
</fileset>
</batchtest>
</junit >
</jacoco:coverage>
</target>
<target name="report" depends ="testCoverage">
<!--<target name="report">-->
<!-- Step 3: Create coverage report -->
<jacoco:report xmlns:jacoco="antlib:org.jacoco.ant">
<!-- This task needs the collected execution data and ... -->
<executiondata>
<file file="${CB_dirsrc}/reports/jacoco.exec"/>
</executiondata>
<!-- the class files and optional source files ... -->
<structure name="JaCoCo Ant MPS Test">
<classfiles>
<fileset dir="${test.classes.dir}/classes" >
<!--<include name="**/*Test*.class"/>-->
<include name="**/*BasicTests.class"/>
<!--<exclude name="**/*BasicTests.class"/>-->
<exclude name="**/*TICPTestHook.class"/>
<exclude name="**/*TRIVTestCase.class"/>
<exclude name="**/*TestContext.class"/>
</fileset>
</classfiles><sourcefiles encoding="UTF-8">
<fileset dir="${test.src.dir}">
<!--<include name="**/*Test*.java"/>-->
<include name="**/*BasicTests.java"/>
<!--<exclude name="**/*BasicTests.java"/>-->
<exclude name="**/*TICPTestHook.java"/>
<exclude name="**/*TRIVTestCase.java"/>
<exclude name="**/*TestContext.java"/>
</fileset>
</sourcefiles>
</structure>
<!-- to produce reports in different formats. -->
<html destdir="${CB_dirsrc}/reports/jacoco"/>
<csv destfile="${CB_dirsrc}/reports/jacoco/report.csv"/>
<xml destfile="${CB_dirsrc}/reports/jacoco/report.xml"/>
</jacoco:report>
</target>
<!-- SONAR-->
<taskdef uri="antlib:org.sonar.ant" resource="org/sonar/ant/antlib.xml">
<classpath path="${sonar_ant_path}/sonar-ant-task-2.2.jar" />
</taskdef>
<target name="analyse" depends="report,init-sonar, sonar-java" description="Perform clean,build,testCoverage and sonar" >
<!--depends="triv.build.all,report,init-sonar, sonar-java"-->
<echo message="This task will do job of executing triv.clean, triv.build.all,testCoverage, init-sonar, sonar-java"/>
</target>
<target name="init-sonar">
<delete dir="${CB_dirsrc}/build/.sonar" />
<!-- MYSQL SONAR DB -->
<property name="sonar.jdbc.url" value="${CB_sonar_db_url_value}" />
<!-- <property name="${CB_sonar_db_driverClassName}" value="${CB_sonar_db_driverClassName_value}" /> -->
<property name="sonar.jdbc.username" value="${CB_sonar_db_username_value}" />
<property name="sonar.jdbc.password" value="${CB_sonar_db_password_value}" />
<!-- SONAR SERVER HOST -->
<property name="sonar.host.url" value="${CB_sonar_host_url}" />
<!-- SONAR PROJECT NAME -->
<property name="sonar.projectName" value="${CB_prd_longname}" />
<property name="sonar.projectKey" value="${CB_sonar_softwareId}" />
<property name="sonar.projectVersion" value="${CB_sonar_project_version}" />
<property name="sonar.sources" value="${CB_sonar_sources}" />
<property name="sonar.tests" value="${test.src.dir}" />
<property name="sonar.verbose" value="true" />
<property name="sonar.dynamicAnalysis" value="reuseReports" />
<property name="sonar.junit.reportsPath" value="${CB_dirsrc}/reports/junit" />
<property name="sonar.surefire.reportsPath" value="${CB_dirsrc}/reports/junit" />
<property name="sonar.java.coveragePlugin" value="jacoco" />
<!--<property name="sonar.java.codeCoveragePlugin" value="jacoco" />-->
<property name="reports.dir" value="${CB_dirsrc}/reports" />
<property name="sonar.jacoco.reportPath" value="${CB_dirsrc}/reports/jacoco.exec" />
<property name="sonar.binaries" value="target/classes" />
<property name="sonar.sourceEncoding" value="UTF-8" />
<property name="sonar.javascript.jstestdriver.reportsPath" value="${CB_dirsrc}/reports/junit" />
<property name="jpos.sonar.projectBaseDir" value="jpos/jpos" />
<property name="jpos.sonar.projectName" value="jpos" />
<property name="jpos.sonar.binaries" value="" />
<property name="audit.sonar.projectName" value="audit" />
<property name="callback.client.sonar.projectName" value="callback client" />
<property name="callback.server.sonar.projectName" value="callback server" />
<property name="consumerapp.sonar.projectName" value="consumerapp" />
<property name="core.sonar.projectName" value="core" />
<property name="external.sonar.projectName" value="external" />
<property name="facade.sonar.projectName" value="facade" />
<property name="facade.bank.sonar.projectName" value="facade bank" />
<property name="facade.citi.sonar.projectName" value="facade citi" />
<property name="facade.ssp.sonar.projectName" value="facade ssp" />
<property name="facade.switch.sonar.projectName" value="facade switch" />
<property name="facade.web.sonar.projectName" value="facade web" />
<property name="openapi.sonar.projectName" value="openapi" />
<property name="product.sonar.projectName" value="product" />
<property name="services.sonar.projectName" value="services" />
<property name="simulator.incoming.sonar.projectName" value="simulator incoming" />
<property name="simulator.incoming.sonar.binaries" value="" />
<property name="simulator.outgoing.sonar.projectName" value="simulator outgoing" />
<property name="simulator.outgoing.sonar.binaries" value="" />
<property name="svmas.sonar.projectName" value="svams" />
<property name="test.sonar.projectName" value="test" />
<property name="test.sonar.binaries" value="target/classes" />
<property name="ui.sonar.projectName" value="ui" />
<property name="ui.csc.sonar.projectName" value="ui csc" />
<property name="ui.msc.sonar.projectName" value="ui msc" />
<property name="ui.occ.sonar.projectName" value="ui occ" />
<property name="ui.purchase.sonar.projectName" value="ui purchase" />
<property name="util.sonar.projectName" value="util" />
<property name="sonar.my.property" value="value" />
</target>
<target name="sonar-java">
<property name="sonar.modules" value="${CB_sonar_java_modules_list}" />
<property name="sonar.language" value="java" />
<property name="sonar.branch" value="Java" />
<!--<property name="sonar.profile" value="${CB_sonar_java_profile}" />-->
<property name="sonar.libraries" value="${CB_sonar_libraries_list}" />
<!-- <sonar:sonar key="${CB_sonar_softwareId}" version="${CB_prd_shortversion}" xmlns:sonar="antlib:org.sonar.ant"/>-->
<sonar:sonar xmlns:sonar="antlib:org.sonar.ant"/>
</target>

ant, copy file with it's directory structure

I am trying to write a ant script to automate the update process of our web application.
When some files is going to be updated, I need to backup that file. my question is how to copy that file to backup directory and also create the directory structure relative to the root directory of my web application?
for example:
${WEB_APP_ROOT}/dir1/file1
${WEB_APP_ROOT}/dir2/subdir1/file2
copied to backup folder should be:
${BACK_UP_DIR}/dir1/file1
${BACK_UP_DIR}/dir2/subdir1/file2
currently, I can only copy all files to backup folder, but if two file with same name but located in different folder will cause problem.
my ant code:
<?xml version="1.0" encoding="UTF-8" ?>
<!-- 对公信贷自动更新Ant任务脚本 created by ggfan#bgzchina.com at 2013.11.14 -->
<project default="patch" basedir=".">
<!-- 引入Weblogic安装目录下的antcontrib包,才能使用if,foreach,propertyregex-->
<taskdef resource="net/sf/antcontrib/antlib.xml">
<classpath>
<pathelement location="/home/weblogic/Oracle/Middleware/modules/net.sf.antcontrib_1.1.0.0_1-0b2/lib/ant-contrib.jar" />
</classpath>
</taskdef>
<!-- 发布目标路径 -->
<property name="target_dir" value="/home/weblogic/amarsoft/ccms/war/CCMS" />
<!-- 数据库连接配置属性 -->
<property name="db_driver" value="oracle.jdbc.OracleDriver" />
<property name="db_url" value="jdbc:oracle:thin:#10.53.1.116:1521:credit" />
<property name="db_user" value="als_sit" />
<property name="db_pswd" value="als_sit" />
<!-- WLST配置 -->
<property name="wl_target_server" value="AdminServer" />
<property name="wl_admin_url" value="t3://10.53.1.117:7001" />
<property name="wl_user" value="weblogic" />
<property name="wl_pswd" value="weblogic123" />
<property name="wl_app_name" value="CCMS" />
<target name="patch">
<!-- 检查是否存在WEB-INF目录,如果有则说明更新了配置文件或者JAVA类需要重新加载应用 -->
<available file="${patch_dir}/WebRoot/WEB-INF" type="dir" property="WEB-INF.present"/>
<!-- 检查是否存在数据库更新脚本 -->
<available file="${patch_dir}/update.sql" type="file" property="sql.present"/>
<!-- 创建备份目录 -->
<mkdir dir="${patch_dir}/backup" />
<!-- 针对单个文件,检查是否更新还是新增,如果是更新则要先备份 -->
<foreach target="move-to-backup" param="theFile">
<path>
<fileset dir="${patch_dir}/WebRoot" />
</path>
</foreach>
<!-- 提醒用户检查更新列表预览 -->
<input message="Is patching preview above correct?" validargs="y,n" addproperty="patch.continue" />
<!-- 用户确认无误则更新 -->
<if>
<equals arg1="${patch.continue}" arg2="y" />
<then>
<!-- 存在WEB-INF目录,则先停止应用 -->
<if>
<equals arg1="${WEB-INF.present}" arg2="true" />
<then>
<echo message="Directory [WEB-INF] found in patching dir, application will be stoped" />
<wldeploy action="stop" graceful="true" name="${wl_app_name}" user="${wl_user}" password="${wl_pswd}"
verbose="true" adminurl="${wl_admin_url}" targets="${wl_target_server}" />
</then>
</if>
<copy todir="${target_dir}" verbose="true">
<fileset dir="${patch_dir}/WebRoot/" />
</copy>
<!-- 存在数据库更新脚本则执行 -->
<if>
<equals arg1="${sql.present}" arg2="true" />
<then>
<sql driver="${db_driver}" url="${db_url}" userid="${db_user}" password="${db_pswd}">
<classpath>
<pathelement location="/home/weblogic/Oracle/Middleware/wlserver_10.3/server/lib/ojdbc6.jar" />
</classpath>
<transaction src="${patch_dir}/update.sql"/>
</sql>
</then>
</if>
<!-- 更新完成后,重启应用 -->
<if>
<equals arg1="${WEB-INF.present}" arg2="true" />
<then>
<echo message="Application will be started again." />
<wldeploy action="start" name="${wl_app_name}" user="${wl_user}" password="${wl_pswd}"
verbose="true" adminurl="${wl_admin_url}" targets="${wl_target_server}" />
</then>
</if>
<echo message="Patching done! " />
</then>
</if>
</target>
<target name="move-to-backup">
<propertyregex property="target.file" input="${theFile}" regexp=".+/${patch_dir}/WebRoot/(.+)" replace="${target_dir}/\1" casesensitive="true" />
<available file="${target.file}" type="file" property="target.file.exist" />
<if>
<equals arg1="${target.file.exist}" arg2="true" />
<then>
<echo message="[UPDATE] ${target.file}" />
<copy todir="${patch_dir}/backup" verbose="false">
<fileset file="${target.file}" />
</copy>
</then>
<else>
<echo message="[ADD ] ${target.file}" />
</else>
</if>
</target>
</project>
In your target move-to-backup you have this copy task:
<copy todir="${patch_dir}/backup" verbose="false">
<fileset file="${target.file}" />
</copy>
When you define a fileset as a single file, it uses the directory containing the file as the base directory for the fileset, and the path to the file is relative to that: simply the name of the file.
You can do something like this instead, so that the path to the file to be copied is relative to the root of your application:
<copy todir="${patch_dir}/backup" verbose="false">
<fileset dir="${WEB_APP_ROOT}">
<include name="${target.file}" />
</fileset>
</copy>
If your file was
${WEB_APP_ROOT}/x/y/z/file.txt
It would then be copied to
${patch_dir}/backup/x/y/z/file.txt

Delete files specified via a zipfileset?

I have the following Ant target which extracts contents from a specific .ZIP archive:
<!-- UNPACK-MATH -->
<target name="unpack-math" depends="init-contrib">
<!-- NOTE: the 'unzip' task doesn't fail when it cannot extract over read-only files; however, 'copy' with a 'zipfileset' does. -->
<first id="math.archive">
<fileset dir="${builddir}" includes="MATH_MF*.zip" />
</first>
<if>
<length string="${toString:math.archive}" when="greater" length="0" />
<then>
<copy todir="${basedir}">
<zipfileset src="${toString:math.archive}" />
</copy>
</then>
<else>
<echo message="No math to unpack." />
</else>
</if>
</target>
What I'd like to do now is "clean up" the files that were extracted. However, the following does not work:
<!-- CLEAN-MATH -->
<target name="clean-math" depends="init-contrib">
<first id="math.archive">
<fileset dir="${builddir}" includes="MATH_MF*.zip" />
</first>
<if>
<length string="${toString:math.archive}" when="greater" length="0" />
<then>
<delete>
<zipfileset src="${toString:math.archive}" />
</delete>
</then>
<else>
<echo message="No math to clean." />
</else>
</if>
</target>
I get the following stack trace:
BUILD FAILED
D:\Development\MForce\Games\gamebuild.xml:214: java.lang.ClassCastException: class org.apache.tools.ant.types.resources.ZipResource doesn't provide files
at org.apache.tools.ant.types.resources.comparators.FileSystem.resourceCompare(FileSystem.java:43)
...
Any ideas?
This solution appears to work, but requires unpacking the .ZIP archive (which lists the files you'd like to delete as some other root) first, which I'd prefer to avoid:
<!-- CLEAN-MATH -->
<target name="clean-math" depends="init-contrib">
<first id="math.archive">
<fileset dir="${builddir}" includes="MATH_MF*.zip" />
</first>
<if>
<length string="${toString:math.archive}" when="greater" length="0" />
<then>
<unzip dest="${builddir}/tmp" src="${toString:math.archive}"/>
<delete>
<fileset dir="${basedir}" includes="**/*">
<present present="both" targetdir="${builddir}/tmp"/>
</fileset>
</delete>
<delete dir="${builddir}/tmp"/>
</then>
<else>
<echo message="No math to clean." />
</else>
</if>
</target>

How can i edit path of a jar in ant

I would like to replace path of an existing jar based on OS .
some thing like below:
in windows : C:/apps/workspace/libs/rpm.jar
in unix : /user-id/projectname/libs/rpm.jar
Is there a way to remove C:/apps/workspace/libs from C:/apps/workspace/libs/rpm.jar .
editing my Question to :
Thanks Liv, But i have lot of libraries like this. right now i am maintaning a text file called "build.start.properties" with all libraries some ting 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
And loading them to classptah using below target
<loadfile property="jars.list.property" srcfile="mybuild/build.start.properties">
<filterchain>
<expandproperties />
<striplinecomments>
<comment value="#" />
</striplinecomments>
<tokenfilter>
<ignoreblank />
</tokenfilter>
<prefixlines prefix="," />
<striplinebreaks />
</filterchain>
</loadfile>
<filelist id="build.libs" dir="" files="${jars.list.property}" />
<pathconvert targetos="unix" property="build_unix.libs" refid="build.libs">
<map from="C:" to="${unix.xenv}" />
<map from="" to="${unix.xenv}" />
</pathconvert>
<pathconvert targetos="windows" property="build_windows.libs" refid="build.libs">
<map from="C:" to="${windows.xenv}" />
<map from="" to="${windows.xenv}" />
</pathconvert>
<path id="build.classpath.id">
<pathelement path="${build_windows.libs}" />
<pathelement path="${build_unix.libs}" />
</path>
<echo message="Build Libraries classpath: ${toString:build.classpath.id}" />
</target>
from the above target build.classpath.id looks like
/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
When i work on unix I have to pic only jar names from file "build.start.properties" and update path like this
/WebContent/WEB_INF/lib/gwt-servlet.jar:/WebContent/WEB_INF/lib/gwt-user.jar:/WebContent/WEB_INF/lib/gwt-dev.jar:/WebContent/WEB_INF/lib/gwt-soyc-vis.jar:/WebContent/WEB_INF/lib/log4j-1.2.15.jar:/WebContent/WEB_INF/lib/gwt-log-3.0.3.jar:/WebContent/WEB_INF/lib/gwt-math-2.1.jar:/WebContent/WEB_INF/lib/gwt-math-server-2.1.jar:/WebContent/WEB_INF/lib/gwt-commons-logging-0.3.jar:/WebContent/WEB_INF/lib/gwt-commons-logging-service-0.3.jar
Always use relative paths, that way you wont' be relying on library being at given location and on underlying OS.
Although this does not answer what you exactly asked for, but the suggestion will help you in the long run. Also, if possible, use Ivy + Ant (or Maven) to manage dependency.
you can use the ant task -- the folliwng is taken from the documentation (http://ant.apache.org/manual/Tasks/condition.html):
<condition property="isMacOsButNotMacOsX">
<and>
<os family="mac"/>
<not>
<os family="unix"/>
</not>
</and>
</condition>

Resources