Calling 2 ivy files sequentially - ant

I'm trying to call 2 retrieves one after the other.
When my ivy_portlet.xml is present, the second call is not executed.
When my ivy_portlet.xml is not present the second call retrieves the content of ivy.xml
When the 2 files are there, only the first one is executed.
What am I missing?
<if>
<available file="${basedir}/ivy_portlet.xml" />
<then>
<echo message="Getting runtime portlet dependencies using Ivy project's configuration" />
<ivy:retrieve pattern="${project.lib.dir}/[conf]/[artifact]-[revision](-[classifier]).[ext]" file="${basedir}/ivy_portlet.xml"/>
</then>
</if>
<if>
<available file="${basedir}/ivy.xml" />
<then>
<echo message="Getting deps using Ivy project's configuration" />
<ivy:retrieve pattern="${project.lib.dir}/[conf]/[artifact]-[revision](-[classifier]).[ext]" file="${basedir}/ivy.xml"/>
</then>
</if>

The ant code looks fine, I even tested it locally (without the ivy retrieve tasks) and both if statements executed. When both files are present and the first ivy retrieve fires, does the retrieve complete successfully without error or failure? Maybe it's getting short-circuited with a failure. Seeing the logs could help here.

Here's the trick:
A call to resolve must be made when using a file name different from ivy.xml.
<ivy:resolve file="${rpm.homedir}/Builder/ivy_portlet.xml"/>

Related

Conditional ivysettings file in Ant

I am trying to adapt an Ant build.xml script to be able to work in both our local office network and within AWS. As such, I have to use a different ivysettings.xml file depending on where the build is happening. In both cases the build is kicked off in Jenkins. My idea was to inject a property 'aws=true' when kicked off from AWS and have the property absent otherwise. We are using Ant 1.7.1 local and a newer version in AWS but I'm not able to see which one right now, build.xml should be able to run on both so 1.7.1 is the limit. I could get this upgraded if necessary.
Can someone help me with the syntax required to adapt this piece of the build.xml file for this purpose?
<!-- Resolve dependencies -->
<target name="resolve" description="retrieve dependencies with ivy">
<ivy:settings file="ivysettings.xml"/>
<ivy:retrieve sync="true"/>
</target>
If aws=true I want to use a file called ivysettings_aws.xml, else ivysettings.xml.
Thank you.
I figured this out using ant_contrib.
<!-- Resolve dependencies -->
<target name="resolve" description="retrieve dependencies with ivy">
<if>
<equals arg1="${aws}" arg2="true" />
<then>
<ivy:settings file="ivysettings_aws.xml"/>
</then>
<else>
<ivy:settings file="ivysettings.xml"/>
</else>
</if>
<ivy:retrieve sync="true"/>
</target>
Works.
Would the following be simpler?
<property name="ivy.settings" value="ivysettings.xml"/>
<target name="resolve" description="retrieve dependencies with ivy">
<ivy:settings file="${ivy.settings}"/>
..
</target>
Alternate settings files are then specified as follows:
ant -Divy.settings=ivysettings_aws.xml ..
You should use the new if/unless feature introduced with Ant 1.9.1 to get rid of an additional dependency to antcontrib, which is out of service btw., latest release 1.0b3 nearly 10 years ago.
Something like :
<project
xmlns:if="ant:if"
xmlns:unless="ant:unless"
>
<!-- Resolve dependencies -->
<target name="resolve" description="retrieve dependencies with ivy">
<ivy:settings file="ivysettings_aws.xml" if:true="${aws}"/>
<ivy:settings file="ivysettings.xml" unless:true="${aws}"/>
<ivy:retrieve sync="true" />
</target>
</project>
Alternatively use the solution proposed by Mark O' Connor, but you need to remember changing the -Divy.settings=... parameter to meet your needs.

How to verify wheter ${property}.attribute is set in ant

I have multiple projects. Each of the project may or may not have a dependent classes. If I have dependent classes I have to build a jar based on the java files in the class property and add to project1 jar if the property is specified or it should be ignored.
Now I have to dynamically loop through all of the projects and in the target i have to test for the existance of the property and build if the property exist.
<target name="test">
<foreach list="${projects}" target="test2" param="project"/>
</target>
<target name="test2">
<!-- Here i have to test wheter ${project}.class exist or not-->
</target>
The following is a sample property file
projects=project1,project2,...
project1.class=class1.java,class2.java
Here project2 doesn't have a .class property,So it should not build a dependency jar. How can I test the existance of the property . I know is set can be used to know the status of property but this comes dynamically can someone help on this ?
You are on the right track with <isset>:
<target name="test2">
<if>
<isset property="${project}.class"/>
<then>
<echo message="${project}.class exists -- let's run a build"/>
</then>
</if>
</target>

Creating an ear-File with ant

I am new to ant i referred many sites , i need to build.xml for my project which consists
of two modules i have application.xml file which represents corresponding war file
so my question is it sufficient to add the application.xml file
<ear destfile="${dist.dir}/${ant.project.name}.ear" appxml="${conf.dir}/application.xml">
<metainf dir="${build.dir}/META-INF"/>
<fileset dir="${dist.dir}" includes="*.jar,*.war"/>
</ear>
whether this will refer the corresponding war files or i need to compile the whole scenario please let me know. how solve this.
I'm not 100% sure what you're asking.
In order to use the <ear> task, you already need to have compiled the required jars and wars.
If those jars and wars have already been built, you simply refer to them in your <ear> task as you did in your example. The application.xml must already exist before you build your ear. The application.xml doesn't build the jars and wars, you have to do that.
If you haven't already built the wars and jars, you need to do that first. A general outline of a build.xml looks something like this:
<project name="foo" basedir="." default="package">
<!-- Some standard properties you've defined -->
<property name="target.dir" value="${basedir}/target"/>
<property name="xxx" value="yyy"/>
<property name="xxx" value="yyy"/>
<property name="xxx" value="yyy"/>
<!-- Compile properties that allow overrides -->
<property name="javac.nowarn" value="false"/>
<property name="javac.listfiles" value="false"/>
<property name="javac.srcdir" value="source"/>
<property name="javac.distdir" value="${target.dir}/classes"/>
<target name="clean"
description="cleans everything nice and shiny">
<delete dir="${target.dir}"/>
</target>
<target name="compile"
description="Compiles everything">
<mkdir dir="${javac.distdir}"/>
<javac srcdir="${javac.srcdir}"
destdir="${javac.destdir}"
[...]
[...]/>
</target>
<target name="package.jar"
depends="compile"
description="Package jarfile">
<jar destfile="${target.dir}/jarname.jar"
[...]
[...]/>
</target>
<target name="package.jar2"
depends="compile"
description="Package jarfile">
<jar destfile="${target.dir}/jarname2.jar"
[...]
[...]/>
</target>
<target name="package.war"
depends="compile"
description="Package jarfile">
<war destfile="${target.dir}/jarname.jar"
[...]
[...]/>
</target>
<target name="package"
depends="package.jar"
description="Make the ear">
<ear destfile="${target.dir}/earfile.ear"
[...]/>
</target>
</project>
Basically, it consists of a bunch of targets and each target does one task. You can have targets depend upon other targets. For example, this particular build.xml will automatically run the package task. The package task depends upon the package.jar task which depends upon the compile task. Thus, the build.xml file will first call compile, then package.jar, then package.
The important thing to remember is that you don't specify the order of the events. You let Ant figure that out, and you let Ant figure out what you need to do. Let's say you've modified a java source file. Ant knows that it has to recompile only that one file. It also knows that it might have to rebuild the jarfile that contains that classfile. And, it then knows it has to rebuild the ear. Most tasks can figure it out on their own, and you don't do a clean for each build. (You notice that the clean target isn't called by package or compile. You have to call it manually).
The only other thing I recommend is that you try to keep your work area clean. Any files you create should be put into the ${target.dir} directory. That way, when you do a clean, you only have to delete that one directory.
I hope this answer your question.

subant on condition

I'd like to execute subant on some condition. something like:
<if>
<equals value="value1" property="${some.property">
<then>
<subant target="#{target}" failonerror="true" inheritall="false">
<buildpath refid="some-ref1" />
</subant>
</then>
<else>
<subant target="#{target}" failonerror="true" inheritall="false">
<buildpath refid="some-ref2" />
</subant>
</else>
</if>
But can't find a way to do it. Read the ant manual and googled, but no solution is found.
Thanks.
I believe the error may lie in your equals tag. Instead of using the 'value' and 'propery' attributes, try using 'arg1' and 'arg2', i.e.:
<equals arg1="value1" arg2="${some.property}">
Check out the examples in the ant-contrib doc: http://ant-contrib.sourceforge.net/tasks/tasks/if.html.
If the problem is that your 'if', 'then', and/or 'else' tags are not resolving properly, then you may be missing the ant-contrib libraries. Ant-contrib is not natively included with ant, but you can download it here: http://sourceforge.net/projects/ant-contrib/files/
Per the ant-contrib site (http://ant-contrib.sourceforge.net/), here's what you must do to install ant-contrib:
Option 1: Copy ant-contrib-0.3.jar to the lib directory of your Ant installation. If you want to use one of the tasks in your own project, add the lines
<taskdef resource="net/sf/antcontrib/antcontrib.properties"/>
to your build file.
Option 2: Keep ant-contrib-0.3.jar in a separate location. You now have to tell Ant explicitly where to find it (say in /usr/share/java/lib):
<taskdef resource="net/sf/antcontrib/antcontrib.properties">
<classpath>
<pathelement location="/usr/share/java/lib/ant-contrib-0.3.jar"/>
</classpath>
</taskdef>
Please look up a <target if="${some.property}>. You may want another target with an unless.
If the property has to do with a file existing, see Ant task to check a file exists?. Even if this is not your main concern, I am sure you can get the idea from the accepted answer.
Do you mean calling another target
if so here is
<if>
<equals value="value1" property="${some.property">
<then>
<antcall target="#{target}" failonerror="true" inheritall="false">
</then>
<else>
<antcall target="#{target}" failonerror="true" inheritall="false">
</else>
</if>

Deploy a app in weblogic only if it is not already present in it using ant wldeploy task

how can i deploy a app in weblogic only if it is not present in it using wldeploy ant task
when i run ant testapp it deploys fresh everytime over existing app as far as i could see in console messages (ie in sysout).
i call this ant target as dependency in some other target, and i want this to run only if app is not already present in weblogic server (to be more efficient)
<target name="testapp" depends="init-wls">
<wldeploy action="deploy" verbose="true" debug="true"
name="testapp" failonerror="false"
...
source="testapp.war"/>
</target>
an interesting question. I'm not sure if wldeploy can do what you want. One approach that might work would be to use the wlconfig ant task. You could use it to get the ApplicationRuntimeMBeans and then query their ApplicationName attributes (again, with wlconfig task) to see if the application is deployed. Not super straightforward but at least you would avoid the application redeployment.
This is just a quick idea off the top of my head so not sure if it is feasible in practice, sorry.... :)
--edit: tried it out, something like this should work, the assumption here is that if we can find the MBean then it is already deployed which should be a valid assumption since these beans live under AppDeployments:
<project name="test" default="deploy">
<property name="domainName" value="ejbTestDomain"/>
<property name="serverName" value="AdminServer"/>
<property name="appName" value="ejbWebEAR"/>
<target name="findApp">
<wlconfig url="t3://localhost:7001" username="weblogic" password="password_for_weblogic">
<query pattern="${domainName}:ServerRuntime=${serverName},Name=${appName},*,Type=ApplicationRuntime" property="app.is.deployed"/>
</wlconfig>
</target>
<target name="deploy" unless="app.is.deployed" depends="findApp">
<echo message="Deploying..."/>
<!-- deploy using wldeploy task -->
</target>
</project>

Resources