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.
Related
I have an testsuite of API testing in SOAP UI.
I want an HTML report of testcases results. I am using basic SOAP UI version. Give me a solution apart from SOAP UI Pro.
Yes, it is possible to generate Junit Style HTML reports using SoapUI Opensource Edition as well.
All you need to do is the execution of tests has to be done
use Apache-Ant software, more details on installing and configuring here
write build script
Here is the sample build script(build.xml):
Note that modify the SOAPUI_HOME(or define environment variable), soapui project file path, results directory path according to your environment.
<project basedir="." default="testreport" name="ant script for testing soapui project">
<property environment="env"/>
<property name="soapui.project" value="/app/demo-soapui-project.xml"/>
<property name="results.dir" value="/tmp/results"/>
<property name="reports.dir" value="${results.dir}/Reports"/>
<property name="html.dir" value="${reports.dir}/html"/>
<target name="execute.project">
<exec dir="${env.SOAPUI_HOME}" executable="testrunner.sh">
<arg line="-raj -f ${results.dir} ${soapui.project}" />
</exec>
</target>
<target name="testreport" depends="execute.project">
<mkdir dir="${reports.dir}"/>
<junitreport todir="${reports.dir}">
<fileset dir="${results.dir}">
<include name="TEST-*.xml"/>
</fileset>
<report format="frames" todir="${html.dir}" />
</junitreport>
</target>
</project>
and execute following command (run soapui project and generate report):
ant
There is also simple way (i.e., every thing configured and readily available envrionment) if you are willing to use this docker image.
Short video also available there on how to.
I have latest Jenkins running on Windows 2003 server.
Under, manage Jenkins:
I have IBM JDK set
I have ant: org.apache.ant_1.7.1.v20100518-1145 set as ant home
I have Jenkins AntExec plug in installed.
I have ant-contrib-0.6.jar inside anthome/lib.
I created a job, and added a build step, Execute Apache Ant, and I have this:
<echo> java home = ${JAVA_HOME}</echo>
<taskdef resource="net/sf/antcontrib/antlib.xml"/>
<project name="Test">
<description> Sample bulid file </description>
<target name="first">
<echo message="The first five letters of the alphabet are:"/>
<antcontrib:for list="a,b,c,d,e" param="letter">
<sequential>
<echo>Letter #{letter}</echo>
</sequential>
</antcontrib:for>
</target>
</project>
when I run build, it fails.
antexec_build.xml:
[echo] ant home = ${ANT_HOME}
[echo] java home = ${JAVA_HOME}
BUILD FAILED
C:\Program Files (x86)\Jenkins\jobs\MCSOWelcome\workspace\antexec_build.xml:13: Problem: failed to create task or type project
Cause: The name is undefined.
Action: Check the spelling.
Action: Check that any custom tasks/types have been declared.
Action: Check that any <presetdef>/<macrodef> declarations have taken place.
I have tried many different things, no luck. Please suggest
AntExec comes bundled with AntContrib. You do not need to add or define it. On the contrary, to disable it, you need to open 2 Advanced... dialogs before you get the option.
What you need to do though, is use antcontrib namespace.
For example, to use for, type:
<antcontrib:for>
I ran into the same problem (I got the same error message: Problem: failed to create task or type project), although I didn't use <antcontrib:for> tag.
If you type some code to the Script source field at the Project configuration > Execute Apache Ant, the plugin doesn't use it as an entire Ant script file, but it inserts into a template script. It appears if you choose to keep the buildfile (Advanced view at Execute Ant Build step). In this case the generated antexec_build.xml Ant script will not be deleted from the Workspace of the Project after the build.
The issue is reproducable with this simple script typed in Script source:
<project>
</project>
The generated antexec_build.xml:
<?xml version="1.0" encoding="utf-8"?>
<project default="antexec_build.xml" xmlns:antcontrib="antlib:net.sf.antcontrib" basedir=".">
<!-- Read additional properties -->
<property file="antexec_build.xml.properties"/>
<!-- Make environment variables accesible via ${env.VARIABLE} by default -->
<property environment="env"/>
<target name="antexec_build.xml">
<!-- Default target entered in the first textarea - begin -->
<project>
</project>
<!-- Default target entered in the first textarea - end -->
</target>
</project>
So that, a solution would be that only include the Ant script that you intend to insert into the <target></target> tag.
I have a zend framework 2 project and i am trying to set up my jenkins so that unit tests can be executed. Jenkins is running on ubuntu and i am developing under Windows 7 with PHPStorm.
build.xml
<target name="phpunit" description="Run unit tests with PHPUnit">
<exec executable="phpunit" failonerror="true">
<arg value="${basedir}/module/Addressbook/test"/>
</exec>
</target>
Folder structure:
project
module
Addressbook
test
AddressbookTest
Controller
AddressbookControllerTest.php
Boostrap.php
phpunit.xml.dist
TestConfig.php
build.xml
Jenkins Output:
phpunit:
[exec] PHPUnit 3.7.13 by Sebastian Bergmann.
[exec]
[exec] PHP Fatal error: Class 'AddressbookTest\Bootstrap' not found in /var/lib/jenkins/workspace/Test/src/module/Addressbook/test/AddressbookTest/Controller/AddressbookControllerTest.php on line 28
PHPStorm on my local machine does this when running phpunit.xml.dist
D:\Zend\ZendServer\bin\php.exe -d auto_prepend_file=D:/Zend/Apache2/htdocs/demoshop/vendor/autoload.php C:\Users\ChristianB\AppData\Local\Temp\ide-phpunit.php --configuration D:/Zend/Apache2/htdocs/demoshop/module/Addressbook/test/phpunit.xml.dist
How can i use that for jenkins?
It looks like your include path isn't setup correctly, I wouldn't use exec directly with PHPUNIT when there's better options.
You should look into using PHING tasks with Jenkins, they work excellent together.
You then setup Jenking to trigger your PHING target to run the unit tests for you via the PHPUNIT task, an example phing target for PHPUNIT:
<target name="phpunit">
<phpunit bootstrap="${srcdir}/tests/bootstrap.php">
<formatter todir="${builddir}/reports" type="xml"/>
<batchtest>
<fileset dir="${srcdir}/tests">
<include name="**/*Test*.php"/>
<exclude name="**/Abstract*.php"/>
<exclude name="${srcdir}/vendor/**"/>
</fileset>
</batchtest>
</phpunit>
<!--
Generate a report from the XML data created..
note: error when using format="frames"
-->
<phpunitreport infile="${builddir}/reports/testsuites.xml"
format="noframes"
todir="${builddir}/reports/tests"
/>
</target>
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
I'm developing an ant script which is calling another ant script using the <ant> task. This ant script is an installer a Java product and is to be used by our customers, who will have ant installed separately.
The script being called uses the antlr task <antlr:ant-antlr3>. To do this I must place the ant-antlr3.jar file in the ant lib directory, as well as adding antlr-3.2.jar to the classpath.
But I don't want to have this dependency of having ant-antl3.jar file in the client's own installed version of ant.
Is there a way of providing the equivalent to ant's command-line '-lib' option to specify other paths for jars to be added to antlib using the <ant> task itself?
I've taken a look at the online docs and there doesn't seem to be a way.
Thanks
I believe the accepted way to do this is to manually set up your classpath in the build file rather than implicitly including it via the global ant lib directory. i.e.
<path id="master-classpath">
<fileset dir="${lib}" />
<fileset file="${findbugs-base}/lib/annotations.jar" />
<pathelement location="${build-classes}" />
</path>
You can then use this path element in any task that can accept classpath args such as javac
<javac
destdir="${out}"
source="1.5"
target="1.5"
debug="true">
<src path="${src}" />
<classpath refid="master-classpath" />
</javac>
This way, the global ant set up isn't a dependency, and you can specify any files you might need for any build, as specifically as you need to (down to a given call or target).
Obviously, this is all to be carried out in the build file you're calling from the clients' build file. This way, when you call out to yours, the classpath will be set up exactly as you desire.
Another far less idiomatic possibility would be to literally shell out with the Exec Task and call ant that way. Obviously, with the provision of the Ant task, the developers of ant don't recommend you doing that. It is an option, nonetheless.
Tim's answer gives most of the story, but in order to run Ant and set JVM options, you'd need to invoke it via the java task.
There is an example of running this way in the Ant docs, here slightly modified to include -lib:
<java
classname="org.apache.tools.ant.launch.Launcher"
fork="true"
failonerror="true"
dir="${sub.builddir}"
timeout="4000000"
taskname="startAnt"
>
<classpath>
<pathelement location="${ant.home}/lib/ant-launcher.jar"/>
</classpath>
<arg value="-lib"/>
<arg value="${path.to.your.antlr.jar}"/>
<arg value="-buildfile"/>
<arg file="${sub.buildfile}"/>
<arg value="${sub.target}"/>
</java>