I want to have a target in my script that records the user's java version in a file format. But for some reason the output to the command "java -version" cannot be recorded.
I tried running java -version > java.txt in terminal, which doesn't work either so I am guessing the result from java -version cannot be captured?
You can use the following exec task in your Ant build.xml:
<exec executable="java">
<arg value="-version"/>
<redirector output="java-version.txt" alwayslog="true"/>
</exec>
Simply use Ant builtin properties, see Ant Manual / Built-in Properties, f.e. :
<echoproperties prefix="java"/>
will print all Java properties.
There are 3 version related properties :
java.version
java.vm.specification.version
java.vm.version
So simply take the appropriate property:
<project>
<echo>
${java.version}
${java.vm.specification.version}
${java.vm.version}
</echo>
<!-- assuming you want ${java.version} -->
<echo file="foobar.txt">Java Version = ${java.version}</echo>
</project>
output :
[echo] 1.7.0_72
[echo] 1.7
[echo] 24.72-b04
Related
I am trying to scan a folder in ant script and extract the version out of it, suppose file name is abc-1.0.0.exe/dmg. I want to get the 1.0.0 in Ant. Is there any way I can do without using ant contrib? I only found help with ant contrib which I don't want to use.
You might be able to use something like this, based on the <pathconvert> task with a regexmapper.
Here's the directory structure in this example:
$ find folder
folder
folder/abc-1.0.0.exe
folder/abc-1.0.0.exe/dmg
Here's the Ant buildfile:
<fileset dir="folder" id="folder"/>
<echo message="file is: ${toString:folder}" />
<pathconvert property="version">
<path path="${toString:folder}" />
<regexpmapper from=".*-(.*).exe.*" to="\1" />
</pathconvert>
<echo message="version is: ${version}" />
Output:
[echo] file is: abc-1.0.0.exe/dmg
[echo] version is: 1.0.0
I use a software (Drops) based on ant script.
I try to dynamically generate the destination path of a file that I want to copy. To do this I execute a linux command line.
In my application, I have this properties :
environment.props.environment_name=recette
application.props.target.gmao=/opt/${environment.props.environment_name}/gmao-ws
I expected Ant to replace ${environment.props.environment_name} by its value at runtime. But it doesn't.
Here is the Ant script that I wrote :
<project xmlns:drops="antlib:com.arcadsoftware.mmk.anttasks" name="deployJar" basedir="." default="main">
<taskdef resource="net/sf/antcontrib/antlib.xml"/>
<taskdef resource="com/dropssoftware/drops/ant/antlib.xml"/>
<loadDropsContext/>
<target name="main">
<!-- get the value of the property "application.props.target.gmao" -->
<propertycopy name="target.dir" from="application.props.target.gmao"/>
<!-- I expect this to print target.dir=/opt/recette/gmao-ws but it print target.dir=/opt/${environment.props.environment_name}/gmao-ws -->
<echoproperties />
<!-- Supposed to copy from /opt/drops/storage/afile.jar to /opt/recette/gmao-ws but the property "target.dir" is wrong -->
<exec executable="sudo">
<arg value="/bin/cp"/>
<arg value="${param.artifacts.root}/${param.jar.root}"/>
<arg value="${target.dir}"/>
</exec>
</target>
</project>
With this input :
param.env=gmao
param.artifacts.root=/opt/drops/storage/
It is supposed to copy a file from the artifacts directory to the /opt/recette/gmao-ws directory. But Ant tried to copy it to /opt/${environment.props.environment_name}/gmao-ws.
I don't understand why Ant doesn't replace ${environment.props.environment_name} by its value.
Is it possible to force Ant to replace the substitution variable by its value ?
Not entirely clear what you're trying to do. The propertycopy task is not part of normal Ant, coming from a 3rd party extension called ant-contrib
I suspect what you're trying to do can be done with normal property substitution. I have provided an example.
Example
A simple example of how to pass in parameters to a build file by setting properties:
$ ant -Dparam.from=AAA -Dparam.to=BBB
build:
[echo]
[echo] sudo
[echo] /bin/cp
[echo] /opt/drops/storage/AAA
[echo] /opt/drops/storage/BBB
[echo]
build.xml
Note the 3 properties declared at the top? These are effectively the default values available for override.
<project name="demo" default="build">
<property name="param.artifacts.root" value="/opt/drops/storage"/>
<property name="param.from" value="fromDir"/>
<property name="param.to" value="toDir"/>
<target name="build">
<echo>
sudo
/bin/cp
${param.artifacts.root}/${param.from}
${param.artifacts.root}/${param.to}
</echo>
</target>
</project>
I think that I find the answer to my question in ant document :
https://ant.apache.org/manual/properties.html
Normally property values can not be changed, once a property is set, most tasks will not allow its value to be modified.
In the case of the software that I use : Drops, it loaded the application properties BEFORE the environment properties.
So application.props.target.gmao is set BEFORE environment.props.environment_name and the ${environment.props.environment_name} cannot be replace.
The answer to my question is seems to be NO, it's not possible to force Ant to replace the substitution variable by its value.
It's done automatically if the variables are loaded in the good order.
The final step of building our java application (using ANT script) involves Inno Setup to package everything in a nice windows installer.
We are now upgrading our ANT script to generate both a 32-bit and a 64-bit version of our application. Our question is thus: how can we parametrize our Inno Setup config file so that it can generate both a x86 and a x64 version (it would thus be called 2x by the ANT script, with a parameter indicating the x86/x64).
In the Inno Setup config file, there is only 1 line that needs to be changed based on this parameter:
ArchitecturesInstallIn64BitMode=x64
And this is how we call Inno Setup command line from ANT:
<exec executable="C:\Program Files (x86)\Inno Setup 5\iscc.exe">
<arg value="/cc" />
<arg value="${dir.create_setup}/CreateSetup.iss" />
</exec>
Any help / hint on how to do this would be greatly appreciated !
Thanks,
Thomas
Use copy task with filtering, may be used for other dynamic values also.
your iss configfile template has :
ArchitecturesInstallIn64BitMode=#32or64#
your build.xml has :
<filter token="32or64" value="${32or64}"/>
<copy file="foobar.iss" tofile="foobaz.iss" filtering="true" overwrite="true"/>
<exec executable="C:\Program Files (x86)\Inno Setup 5\iscc.exe">
<arg value="/cc" />
<arg value="foobaz.iss" />
</exec>
then start your ant file with userproperty 32or64 like that :
ant -f build.xml -D32or64=x64
or
ant -f build.xml -D32or64=x86
copy task with filtering will replace the token #32or64# with the value of userproperty 32or64, so foobaz.iss has either :
ArchitecturesInstallIn64BitMode=x64
or
ArchitecturesInstallIn64BitMode=x86
Our ant build is run using Java 1.7.0 for JAVA_HOME. This way javac and all other Java dependent targets use the correct Java by default.
But 1 ant target from an external supplier does not support (or rather has a bug) using Java 1.7.0. And unlike e.g. javac or a forked junit, this target does not support parameters to switch jvm.
Is it possible to run a specific ant target in a different jvm?
To make Jeanne Boyarsky's suggestion of using the exec Ant task concrete, the following example wraps the exec task in a macro to simplify calling targets with various JVMs. Notice that the JVM is set using the Ant environment variable JAVACMD.
Example Project
<?xml version="1.0" encoding="UTF-8"?>
<project name="run-target-with-specified-java-version" default="test">
<macrodef name="exec-target">
<attribute name="antfile" default="${ant.file}" />
<attribute name="target" />
<attribute name="jvm" default="${java.home}/bin/java" />
<sequential>
<exec executable="ant">
<env key="JAVACMD" value="#{jvm}" />
<arg line='-f "#{antfile}"' />
<arg line="#{target}" />
</exec>
</sequential>
</macrodef>
<target name="echo-java-version">
<echo message="Java version: ${java.version}" />
</target>
<target name="test">
<exec-target target="echo-java-version" />
<property name="java1.6"
location="/usr/lib/jvm/jdk1.6/bin/java" />
<exec-target target="echo-java-version" jvm="${java1.6}" />
</target>
</project>
Output
test:
[exec] Buildfile: /home/your/project/build.xml
[exec]
[exec] echo-java-version:
[exec] [echo] Java version: 1.7.0
[exec]
[exec] BUILD SUCCESSFUL
[exec] Total time: 0 seconds
[exec] Buildfile: /home/your/project/build.xml
[exec]
[exec] echo-java-version:
[exec] [echo] Java version: 1.6.0
[exec]
[exec] BUILD SUCCESSFUL
[exec] Total time: 0 seconds
BUILD SUCCESSFUL
Total time: 2 seconds
You can use the exec task to run the build file with that target defined to run as a parameter. It could be running in a different JVM since you can pass the JVM to that exec call.
Note that you'd have to refactor the target to rely on files for communication rather than setting properties. Since it would be in a different JVM, it obviously can't rely on memory.
You can run a target in a different JVM (we do it all the time). You just need to use fork:
<javac srcdir="${src}"
destdir="${build}"
fork="yes"
/>
But I sense you are aware of this, so how about running the external ANT task as it is, and rest of them (lets say you have 3 more javac tasks) in the JVM you want. This can be achieved by setting a property file. See javac task
It is possible to use different compilers. This can be specified by either setting the global build.compiler property, which will affect all tasks throughout the build
So this property will affect your 3 tasks and run them in the JVM you specified (say 1.7) and you can set the default JAVA_HOME to whatever your external library task needs.
According to the man page of make, -n option does the following job:
Print the commands that would be executed, but do not execute them.
I am looking for an option which acts the same in Apache Ant.
Horrific, but here it is. We can hack the targets at runtime using some code inside a <script> tag*. The code in do-dry-run below sets an unless attribute on each of your targets, and then sets that property so that none of them executes. Ant still prints out the names of targets that are not executed because of an unless attribute.
*(JavaScript script tags seem to be supported in Ant 1.8+ using the Oracle, OpenJDK and IBM versions of Java.)
<?xml version="1.0" encoding="UTF-8"?>
<project default="build">
<target name="targetA"/>
<target name="targetB" depends="targetA">
<echo message="DON'T RUN ME"/>
</target>
<target name="targetC" depends="targetB"/>
<target name="build" depends="targetB"/>
<target name="dry-run">
<do-dry-run target="build"/>
</target>
<macrodef name="do-dry-run">
<attribute name="target"/>
<sequential>
<script language="javascript"><![CDATA[
var targs = project.getTargets().elements();
while( targs.hasMoreElements() ) {
var targ = targs.nextElement();
targ.setUnless( "DRY.RUN" );
}
project.setProperty( "DRY.RUN", "1" );
project.executeTarget( "#{target}" );
]]></script>
</sequential>
</macrodef>
</project>
When I run this normally, the echo happens:
$ ant
Buildfile: build.xml
targetA:
targetB:
[echo] DON'T RUN ME
build:
BUILD SUCCESSFUL
Total time: 0 seconds
But when I run dry-run, it doesn't:
$ ant dry-run
Buildfile: build.xml
dry-run:
targetA:
targetB:
build:
BUILD SUCCESSFUL
Total time: 0 seconds
Ant has no dry-run option as make or maven have. But you could run the ant file step by step it in debugging mode under eclipse.
No I belive. There is no such way by default in Ant. And many unstisfying attempts you would find on google. But I have searched once and was unsuccessful.
It would be a useful feature, but not easily implemented.
Make and ANT are architecturally quite different. ANT doesn't run external OS commands, instead, most ANT "tasks" execute within the same Java thread.
It would be possible to emulate a "dry run" as follows:
<project name="Dry run" default="step3">
<target name="step1" unless="dry.run">
<echo>1) hello world</echo>
</target>
<target name="step2" depends="step1" unless="dry.run">
<echo>2) hello world</echo>
</target>
<target name="step3" depends="step2" unless="dry.run">
<echo>3) hello world</echo>
</target>
</project>
Running ANT as follows will print the target name but won't execute the enclosed tasks:
$ ant -Ddry.run=1
Buildfile: build.xml
step1:
step2:
step3:
BUILD SUCCESSFUL
Total time: 0 seconds
Create a special target in your buildscript that does some echoing only i.e. to check whether properties, path .. are resolved correctly.
see https://stackoverflow.com/a/6724412/130683 for a similar question answered.
For checking the details of your ant installation use ant -diagnostics