Alter ivy.xml file called in as transitive dependency - ivy

I am using ivy to resolve dependencies, the direct dependency I have is for jdom with the entry on ivy.xml as
<dependency org="org.jdom" name="jdom" rev="2.0.2"/>
This calls in several other jars as transitive dependencies - unfortunately one, jaxen, has a non working dependency as per Jaxen bug and various questions on SO here and here. Unfortunately these questions are answered with a fix to a maven pom.
My question is what can I do in my ivy setup to use a corrected ivy file for jaxen or just suppress jaxen trying to load findbugs and cobertura?

Ivy allows to exclude specified dependencies from resolution.
This will exclude jaxen from the dependency:
<dependency org="org.jdom" name="jdom" rev="2.0.2">
<exclude module="jaxen"/>
</dependency>
This will exclude cobertura and findbugs
<dependency org="org.jdom" name="jdom" rev="2.0.2">
<exclude name="maven-cobertura-plugin" />
<exclude name="maven-findbugs-plugin" />
</dependency>

Related

Why does Artifactory require an explicit artifact for some Ivy dependencies

I have an Artifactory server that I use to resolve Ivy dependencies. When I want to add a dependency to my ivy.xml, I sometimes have to add an explicit nested <artifact> tag, and I don't understand why.
Example A:
<dependency org="com.google" name="guava" rev="[7,)" conf="compile,runtime" />
Example B
<dependency org="com.twelvemonkeys.common" name="common-image" rev="3.0.1" conf="compile,runtime">
<artifact name="common-image" ext="jar"/>
</dependency>
Looking at the cached dependencies in the Artifactory tree view, there's nothing that indicates that the last example should need extra info to resolve the dependency, but Artifactory suggests it itself, and the resolution doesn't work without out.
I'm using Ivy against a repository with Maven layout. My settings where generated by Artifactory and look something like:
<?xml version="1.0" encoding="UTF-8"?>
<ivy-settings>
<settings defaultResolver="main" />
<resolvers>
<chain name="main">
<ibiblio
name="public"
m2compatible="true"
root="http://example.org/artifactory/remote-repos" />
</chain>
</resolvers>
</ivy-settings>
Why does Artifactory require an explicit artifact for some Ivy dependencies and not for others?
Edit 20151005: Added Ivy settings example
The tool performing the dependency resolution is the Ivy client and not Artifactory.
Based on the dependency deceleration the Ivy resolver decides which artifact to request from the repository (in your case it is Artifactory).
The artifact feature provides more control on a dependency for which you do not control its ivy file.
It enables to specify the artifacts required, if the dependency has no ivy file.
For more information about the artifact feature and when it should be used consult the Ivy documentation.

Ivy : dependency between 2 dependencies

I am looking for a way to declare "a dependency between 2 dependencies".
For instance, in my module, I have in ivy.xml the following lines :
<dependencies>
<dependency org="org.slf4j" name="slf4j-api" rev="${slf4japiversion}"/>
<dependency org="ch.qos.logback" name="logback-classic" rev="1.0.13" conf="test->default"/>
</dependencies>
My problem is that logback-classic 1.0.13 depends on slf4j-api 1.7.5 and my module depends on 1.6.6 (value of slf4japiversion).
I can't change slf4japiversion but in the future it could be upgraded by someone else.
Is there a way to declare the dependency on logback to retrieve the version compatible with my slf4j-api version ?
You can specify an override directive to force resolution to a particular version of a dependency:
<dependencies>
<dependency org="org.slf4j" name="slf4j-api" rev="1.6.6" conf="compile->default"/>
<dependency org="ch.qos.logback" name="logback-classic" rev="1.0.13" conf="runtime->default"/>
<override org="org.slf4j" module="slf4j-api" rev="1.6.6"/>
</dependencies>
A word of warning, when downgrading dependencies. If logback uses a feature only supported by version 1.7.5 then the solution will not work. It's far more likely a library is backwardly compatible.

Ivy Retrieve with Classifiers

I have the following ivy.xml:
<ivy-module version="1.0"
xmlns:maven="http://maven.apache.org">
<configurations>
...
</configurations>
<dependencies>
<dependency org="com.foo" name="fubur"
rev="1.3" conf="runtime->default"/>
<dependency org="com.snafu" name="barfu"
rev="1.4" conf="runtime->default">
<artifact name="barfu"
maven:classifier="ID_10T"
type="jar" ext="jar"/>
</dependency>
</dependencies>
</ivy-module>
In my build.xml, I want to retrieve all of my jars for the war I'm building:
<ivy:retrieve
pattern="${lib.dir}/[artifact]-[classifier]-[revision].[ext]"
conf="runtime"/>
No, that won't work... There's no classifier in fubar-1.3.jar. It will download as fubar--1.3.jar
<ivy:retrieve
pattern="${lib.dir}/[artifact]-[revision].[ext]"
conf="runtime"/>
That's no good either. barfu-ID_10T-1.4.jar will download as barfu-1.4.jar.
I would like the jars in my war to be included as barfu-ID_10T-1.4.jar and fubar-1.3-jar`. Is there an easy way of doing that? I know I could create two different configurations, but that is overkill. I'd rather just have the jars miss-named since it really doesn't affect the war itself.
Use parentheses to specify optional components of an attribute pattern:
<ivy:retrieve
pattern="${lib.dir}/[artifact](-[classifier])-[revision].[ext]"
conf="runtime"/>

How to take two revisions of the same jar?

I have two versions of the same jar (3.2 and 2.2.1) I need to use both of them but ivy evicts older revision. How to configure ivy to take two versions?
<dependency org="asm" name="asm-all" rev="3.2">
<artifact name="asm-all" type="jar"/>
</dependency>
<dependency org="asm" name="asm-all" rev="2.2.1">
<artifact name="asm-all" type="jar"/>
</dependency>
You need to use ivy configurations. This is a very flexible mechanism to manage arbitrary groups of dependencies.
The example below places each version of the jar onto a separate configuration. This can be used later to create two classpaths, using the ivy cachepath task.
Example
ivy.xml
<ivy-module version="2.0">
<info organisation="com.myspotontheweb" module="demo"/>
<configurations>
<conf name="compile1" description="Required to compile application1"/>
<conf name="compile2" description="Required to compile application2"/>
</configurations>
<dependencies>
<!-- compile1 dependencies -->
<dependency org="asm" name="asm-all" rev="3.2" conf="compile1->master"/>
<!-- compile2 dependencies -->
<dependency org="asm" name="asm-all" rev="2.2.3" conf="compile2->master"/>
</dependencies>
</ivy-module>
Notes:
Version 2.2.1 does not exist in Maven Central
Note the configuration mapping "??? -> master". In Maven the remote master configuration mapping resolves to the main module artifact without dependencies. (See)
build.xml
<project name="demo" default="init" xmlns:ivy="antlib:org.apache.ivy.ant">
<target name="init" description="Use ivy to resolve classpaths">
<ivy:resolve/>
<ivy:report todir='build/ivy' graph='false' xml='false'/>
<ivy:cachepath pathid="compile1.path" conf="compile1"/>
<ivy:cachepath pathid="compile2.path" conf="compile2"/>
</target>
<target name="clean" description="Clean built artifacts">
<delete dir="build"/>
</target>
<target name="clean-all" depends="clean" description="Additionally purge ivy cache">
<ivy:cleancache/>
</target>
</project>
Notes:
Always a good idea to generate an ivy report. It will tell you which dependencies exist on which ivy configuration.
This example shows ivy managing ANT paths. You can also use ivy configurations with the ivy retrieve task to populate a local "lib" directory when assembling something like a webapp WAR file.

Make Ivy recognize ant#ant and ant#org.apache.ant are conflicts

My build has both ant-1.7.0.jar and ant-1.6.2.jar in it, and this is breaking tests. Looking at the ivy:report, it appears that 1.6.2 is resolved as ant#ant, and 1.7 is ant#org.apache.ant.
So how can I configure Ivy to treat ant and org.apache.ant as the same organization?
You can't but you can create a global exclusion:
<ivy-module version="2.0">
..
..
<dependencies>
..
..
<!-- Global exclusions -->
<exclude org="ant" module="ant"/>
</dependencies>
</ivy-module>