getting error in ivy.xml throwing exception - ivy

I am getting the below exception upon ivy-configure tag , i have configured the ivy configure tag in my build-ivy.xml as shown below
my ivy.xml is at the below path..
/ops/ivy/ivy.xml
my ivy-settings.xml is at..
/ops/ivy/ivysettings.xml
and my ivy:configure entry in build.xml as shown below ...
<!-- Ivy -->
<target name="prepare" description="Ivy setting load">
<echo message="Saral in Prepare"/>
<delete dir="${project_dependencies}"/>
<mkdir dir="${project_dependencies}"/>
<path id="classpath">
<fileset dir="lib">
<include name="${ops.dir}/ivy/ivy-2.3.0.jar"/>
</fileset>
</path>
<ivy:configure file="${ops.dir}/ivy/ivysettings.xml" />
<ivy:retrieve type="jar" pattern="${project_dependencies}/[artifact].[ext]"/>
</target>
the error that i am getting is ...please advise where i need to configure ivy.xml
prepare:
[echo] Saral in Prepare
[delete] Deleting directory C:\DTSTOTALUPLOADED\Glacier\project_dependencies
[mkdir] Created dir: C:\DTSTOTALUPLOADED\Glacier\project_dependencies
[ivy:configure] :: Apache Ivy 2.3.0 - 20130110142753 :: http://ant.apache.org/ivy/ ::
[ivy:configure] :: loading settings :: file = C:\DTSTOTALUPLOADED\Glacier\ops\ivy\ivysettings.xml
[ivy:retrieve] C:\DTSTOTALUPLOADED\Glacier\ivy\ivy.xml (The system cannot find the path specified) in file:/C:/DTSTOTALUPLOADED/Glacier/ivy/ivy.xml
BUILD FAILED
folks please advise on this..!

Ivy is designed to manage a software projects dependencies, using an ivy file that is normally committed locally into the source code.
For a working example see:
How to avoid copying dependencies with Ivy
Additional info
Location of ivy file
Typically the project files look something like the following:
├── build.xml
├── ivy.xml <-- Ivy file detailing project dependencies
└── src
└── main
└── java
└── myorg
└── MyClass.java
Cleanup targets
I would suggest moving build cleanup logic into a separate set of targets and additionally leverage the cleancache ivy task.
<target name="clean" description="Cleans up files created by build">
<delete dir="build"/>
<delete dir="lib"/>
</target>
<target name="clean-all" depends="clean" description="Additionally purge ivy cache">
<ivy:cleancache/>
</target>
Managing classpath
A more efficient way to manage the build classpath is to use the ivy cachepath task instead of retrieve.
This approach is especially powerful if you use ivy configurations, allowing you to control multiple classpaths.
Bootstrapping ivy
I don't think the following code is redundant:
<path id="classpath">
<fileset dir="lib">
<include name="${ops.dir}/ivy/ivy-2.3.0.jar"/>
</fileset>
</path>
Adding the ivy jar onto a project path after ANT is started would be too late. Check your $ANT_HOME/lib or ~/.ant/lib directories. I'll bet the ivy jar is there already?

Related

How do I use AWS CodeArtifact with Apache Ivy?

I have set up an AWS CodeArtifact repository, and used Maven to publish a jar to it.
I want to use that jar in an Ant task, and I'm trying to use Apache Ivy to download the dependency.
I've successfully used Ivy to download public libraries from the Maven central repository, but I don't know how to add my AWS CodeArtifact repository to Ivy. The official Ivy tutorials are very hard for me to understand.
The solution was to switch from Ivy to the Maven Resolver Ant Tasks - much better documented and easier to understand.
I can now load AWS CodeArtifact dependencies from my ant task with something like this (after doing the Maven setup instructions from AWS CodeArtifact). This downloads the Maven resolver jar as part of the process:
<property name="maven.install.version" value="1.3.0"/>
<property name="ant.jar.dir" value="${user.home}/.ant/lib"/>
<property name="maven.jar.file" value="${ant.jar.dir}/maven-resolver-ant-tasks.jar"/>
<target name="load-maven-dependencies" depends="init-maven">
<resolver:resolve>
<dependencies>
<dependency coords="group:artifact:version"/>
</dependencies>
<path refid="main.classpath" classpath="compile"/>
</resolver:resolve>
</target>
<target name="init-maven" depends="download-maven">
<path id="maven.lib.path">
<fileset dir="${ant.jar.dir}" includes="${maven.jar.file}"/>
</path>
<taskdef resource="org/apache/maven/resolver/ant/antlib.xml" uri="antlib:org.apache.maven.resolver.ant" classpathref="maven.lib.path"/>
</target>
<target name="download-maven" unless="offline">
<mkdir dir="${ant.jar.dir}" />
<get src="https://search.maven.org/remotecontent?filepath=org/apache/maven/resolver/maven-resolver-ant-tasks/${maven.install.version}/maven-resolver-ant-tasks-${maven.install.version}-uber.jar" dest="${maven.jar.file}" usetimestamp="true"/>
</target>
You can then use main.claspath in your taskdef, like this:
<taskdef name="customTask" classname="com.prosc.CustomAntTask" classpathref="main.classpath" />

Ivy/Maven Resolve: Don't pull transitive "provided" jars

I'm using Ivy for my projects, but we're using Artifactory as our jar repository. I actually use <ivy:makepom> Ant task to create a Maven pom.xml, so I can deploy the jars and wars back to my Maven repository via the Maven deploy:deploy workflow.
I build a big jar called common-all.jar that requires about 30 jars for its compilation. I specify about 10 jars, and Ivy pulls down the dependencies. As part of the compile process, I specify the log4j jar, and some JBoss jars. These jars, of course, will be provided by our environment.
With this Jar, I also a bunch of wars. I specify the common-all.jar as part of my dependency, and the 30 jars that common-all.jar requires are also pulled down. All is well and good.
The problem is when I build the war. I do not want the JBoss jars or the log4j jars included as part of the war. These will be provided by the environment. I've marked them as provided in the pom.xml file. when I build common-all.jar.
Now, the question is how do I specify that I want these when I compile the code for the war, but I don't want to include them in my war itself.
Here's a sample of my ivy.xml file.
How can I specify that the common-all.jar requires certain specific jars for compilation, but when I build it in a war, I don't want all of these jars
<ivy-module version="1.0">
<info
organisation="com.travelclick"
module="TC-AppUtil"
revision="4.1"
status="release"/>
<configurations>
<conf name="default" visibility="public"
description="The single built artifact. Nothing else"/>
<conf name="compile" visibility="public"
description="The master module and transitive dependencies"/>
<conf name="provided" visibility="public"
description="Needed for compile. Will be provided outside or war"/>
<conf name="runtime" visibility="public"
description="Not required for compile, but for runtime"
extends="compile"/>
<conf name="default" visibility="public"
description="The default configuration"
extends="runtime"/>
<conf name="test" visibility="private"
description="Required for testing" extends="runtime"/>
</configurations>
<dependencies>
<!-- Normal Compile Dependencies -->
<dependency org="ximpleware" name="vtd-xml"
rev="2.5" conf="compile->default"/>
<dependency org="com.travelclick" name="common-all"
rev="4.1" conf="compile->compile,runtime"/>
<!-- Testing -->
<dependency org="junit" name="junit"
rev="4.10" conf="test->default"/>
</dependencies>
</ivy-module>
You haven't demonstrated how you declare the common-all dependency, so I'll make up the following example:
<dependency org="mygroup" name="common-all" rev="1.0" conf="compile->default;provided"/>
The magic is the configuration mapping:
The local "compile" configuration is mapped to the common module and its default (compile) scope dependencies, and
The local "provided" configuration is mapped to the common module and its provided scope dependencies.
Inside your build file the configurations are used as follows:
<project name="demo" default="build" xmlns:ivy="antlib:org.apache.ivy.ant">
<target name="resolve">
<ivy:resolve/>
<ivy:cachepath pathid="compile.path" conf="compile"/>
<ivy:cachepath pathid="provided.path" conf="provided"/>
</target>
<target name="compile" depends="resolve">
<javac ...
<classpath>
<path refid="compile.path"/>
<path refid="provide.path"/>
</classpath>
</javac>
</target>
<target name="build" depends="compile">
<ivy:retrieve pattern="build/lib/[artifact].[ext]" conf="runtime"/>
<war ...
<lib dir="build/lib"/>
</war>
</target>
<target name="clean">
<delete dir="build"/>
<ivy:cleancache/>
</target>
</project>

How to copy runtime libraries without the provided ones in IVY

I thought I wouldn't need to ask this but I am not having any progress.
The solution to this question:
How are maven scopes mapped to ivy configurations by ivy actually addresses question but in its theoretical part.
I have this configuration:
<conf name="compile" description="???" />
<conf name="runtime" description="???" extends="compile" />
<conf name="test" description="???" extends="runtime" />
<conf name="provided" description="???" />
Assume I have this dependency:
<dependency org="org.apache.tomcat" name="servlet-api" rev="6.0.16" transitive="false" />
What I want is: when I invoke the ivy:retrieve to copy the libraries to the .war lib directory before bundling it, I want only to copy all runtime (and compile implicitly) but no servlet-api.
so how to use ivy:retrieve then?
<ivy:retrieve conf="WHAT_TO_PUT_HERE" />
and how to configure the dependency:
<dependency conf="WHAT_IS_THE_CONF_MAPPING" org="org.apache.tomcat" name="servlet-api" rev="6.0.16" transitive="false" />
I'm plateauing here, so please any help would be appreciated.
Knowing that the ivy.xml for servlet-api defines the artifact with
conf="master"
So I think the question is how to 'really' map Provided scope of maven to the provided configuration of IVY.
This is how you map a dependency onto the local "provided" configuration:
<dependency org="org.apache.tomcat" name="servlet-api" rev="6.0.16" conf="provided->master"/>
The configuration mapping works as follows:
provided->master
^ ^
| |
Local Remote
config config
As explained in the answer the special "master" configuration contains only the artifact published by this module itself, with no transitive dependencies:
How are maven scopes mapped to ivy configurations by ivy
This means the "transitive=false" attribute is not required.
Update
How you use the configuration is up to you. The first option is simpler, but I prefer the second approach because my configuration reports match my classpath contents
Option 1
You can create a single classpath as follows:
<ivy:cachepath pathid="compile.path" conf="compile,provided"/>
This can then be used in the javac task as follows:
<javac ... classpathref="compile.path">
..
Option 2
Or I prefer to have a one-2-one mapping between configurations and classpaths:
<ivy:cachepath pathid="compile.path" conf="compile"/>
<ivy:cachepath pathid="provide.path" conf="provided"/>
The problem with the latter approach is that the javac task need to have the classpath usage explicitly stated as follows:
<javac ...
<classpath>
<path refid="compile.path"/>
<path refid="provided.path"/>
</classpath>
I think this explicitly explains how you use this special provided scope, but it's really up to you.

Apache Ivy & Settings File

I'm writing my first Ivy configuration for a new Java project and am trying to hook my ivy-settings.xml file up to my buildscript.
I've followed all the tutorials and have correctly added the xmlns:ivy="antlib:org.apache.ivy.ant" namespace to my build.xml file. So far I've tried running my resolve and cleancache targets, which run ivy:resolve and ivy:cleancache respectively, and all seems to be working (Ant can find Ivy).
However...when I run ivy:resolve, it defaults to go right to the public repo. Since my resolvers are written to look in my SVN root, I have to conclude that Ivy does not see my ivy-settings.xml file and is going to the public repos by default.
I am purposely keeping my ivy-settings.xml file as a separate project in source control because it will be used by all my projects.
So my question:
How do I instruct the Ant buildscipt to look for a checked-out version of ivy-settings.xml somewhere else in my file system, not just sitting there locally in the same directory as build.xml?
Change the settings file name to:
ivysettings.xml
If you want to change this default name and location (same directory as build file) use the "settings" task
Update
This is how I ensure that the settings file is loaded before invoking the ivy resolve of cleancache tasks. Create a target called init that is declared as a dependency
<target name="init">
<ivy:settings file="../../ivysettings.xml"/>
</target>
<target name="resolve" depends="init">
<ivy:resolve/>
</target>
<target name="clean" description="Cleanup build directory">
<delete dir="${build.dir}"/>
</target>
<target name="clean-all" depends="init,clean" description="Clean and purge caches">
<!-- Purge the ivy cache -->
<ivy:cleancache/>
</target>

ivy simple shared repository

I am trying to compile all sub projects of one big project at my company into many jars with managed dependencies, so that not everybody who works at one project only needs to download the latest jars from a shared repository.
ivy seems to be the solution for our problem, because ivy says that it integrates with ant (out build system) very well. But I cant get through the tutorials, they are all somehow more confusing than helpful.
All I want to achieve for the beginning is to have two small Projects. The first one has one class with one method, the second one is just calling this method. The fist project should compile into a jar that is then downloaded by the second project from the shared repository.
Thanks for your help.
A multi-module project is described in the documentation:
http://ant.apache.org/ivy/history/latest-milestone/tutorial/multiproject.html
and the source code is available in subversion:
http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/example/multi-project/
The simplified summary of how it works:
Wrapper build
Invokes each individual module build in the correct order. If Module A depends on module B, then B will be built first:
<project xmlns:ivy="antlib:org.apache.ivy.ant" name="build-all" default="build">
<!--
==========================================================================
Use the ivy buildlist task to create an ordered list of sub-project builds
==========================================================================
-->
<target name="build-list">
<ivy:buildlist reference="build-path">
<fileset dir="." includes="modules/**/build.xml"/>
</ivy:buildlist>
</target>
<!--
==============================
Invoke targets in sub-projects
==============================
-->
<target name="build" depends="build-list" description="Invoke build target on sub-projects">
<subant target="build" buildpathref="build-path" />
</target>
</project>
For more information see the buildlist documentation.
Module build
Each module will download it's dependencies at the beginning of it's build
<target name="init">
<ivy:settings file="../../ivysettings.xml"/>
<ivy:resolve/>
</target>
At at the end, will publish it's built artifacts:
<target name="publish" depends="build" description="Publish module artifacts to the respository">
<ivy:publish resolver="${publish.resolver}" pubrevision="${publish.revision}" overwrite="true">
<artifacts pattern="${build.dir}/[artifact].[ext]"/>
</ivy:publish>
</target>
Don't forget that for all this to work each module must declare what it depends on and what it publishes
<ivy-module version='2.0'>
<info organisation='com.myorg' module='mymod'/>
<publications>
<artifact name="mymod" type="jar"/>
</publications>
<dependencies>
..
</dependencies>
</ivy-module>