Retrieve Specific jar to a Folder - ivy

I was to retrieve a jar from ivy cache to a lib folder, below is the ivy.xml code:
<configurations>
<conf name="specificFolder" description="add jar to web-inf/lib folder"/>
</configurations>
<dependencies>
<dependency org="javax.servlet" name="servlet-api" rev="2.4" transitive="false" conf="specificFolder"/>
<dependency org="org.springframework" name="spring-beans" rev="2.5.5" transitive="false" />
<dependency org="org.springframework" name="spring-webmvc" rev="2.5.5" transitive="false" />
<dependency org="org.springframework" name="spring-web" rev="2.5.5" transitive="false" />
<dependency org="org.springframework" name="spring-context" rev="2.5.5" transitive="false" />
<dependency org="org.springframework" name="spring" rev="1.2.6" transitive="false" />
then this is ant target:
<target name="test">
<ivy:retrieve pattern="lib/[artifact](.[ext])" sync="true" type="jar" conf="specificFolder"/>
</target>
But I got "Unresolved Dependency", this anything I am doing wrong?

I reproduced your problem and here is the relevant error message:
[ivy:resolve] ::::::::::::::::::::::::::::::::::::::::::::::
[ivy:resolve] :: UNRESOLVED DEPENDENCIES ::
[ivy:resolve] ::::::::::::::::::::::::::::::::::::::::::::::
[ivy:resolve] :: javax.servlet#servlet-api;2.4: configuration not found in javax.servlet#servlet-api;2.4: 'specificFolder'. It was required from com.myspotontheweb#demo;????? specificFolder
[ivy:resolve] ::::::::::::::::::::::::::::::::::::::::::::::
The root cause is the following dependency declaration:
<dependency org="javax.servlet" name="servlet-api" ... conf="specificFolder"/>
While the configuration exists in your module it does not exist in the remote Maven module. For more details on how see the following answer:
How are maven scopes mapped to ivy configurations by ivy
Working example
ivy.xml
<ivy-module version="2.0">
<info organisation="com.myspotontheweb" module="demo"/>
<configurations>
<conf name="specificFolder" description="add jar to web-inf/lib folder"/>
</configurations>
<dependencies>
<dependency org="javax.servlet" name="servlet-api" rev="2.4" conf="specificFolder->master"/>
<dependency org="org.springframework" name="spring-beans" rev="2.5.5" conf="specificFolder->master"/>
<dependency org="org.springframework" name="spring-webmvc" rev="2.5.5" conf="specificFolder->master"/>
<dependency org="org.springframework" name="spring-web" rev="2.5.5" conf="specificFolder->master"/>
<dependency org="org.springframework" name="spring-context" rev="2.5.5" conf="specificFolder->master"/>
<dependency org="org.springframework" name="spring" rev="1.2.6" conf="specificFolder->master"/>
</dependencies>
</ivy-module>
Notes:
This example uses configuration mappings instead of "transitive=false". The local configuration is "specificFolder" and the remote configuration is the special "master". "master" is provided by Maven modules and means the remote artifact with no dependencies. I think this approach is simpler once it's understood how configurations work. (Very powerful concept in Maven)
what does the little arrow -> do in the ivy dependency section?

Related

Why can't Ivy resolve my configurations

I've got an Ivy and Artifactory setup to publish and depend on builds with.
In Artifactory I have an Ivy file along the lines of:
<?xml version="1.0" encoding="UTF-8"?>
<ivy-module version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd">
<info organisation="org" module="module" branch="HEAD" revision="0.277-SNAPSHOT" status="integration" publication="20140724114055">
</info>
<configurations>
<conf name="compile" visibility="public" description="Default required to compile the full module"/>
<conf name="build" visibility="public" extends="compile" description="Incorporates additional build tools onto the classpath"/>
</configurations>
<publications defaultconf="compile">
<artifact name="module" type="jar" ext="jar"/>
<artifact name="module-src" type="source" ext="zip"/>
<artifact name="module-doc" type="doc" ext="zip"/>
</publications>
<dependencies>
<dependency org="junit" name="junit" rev="4.8.1" conf="compile->*"/>
<dependency org="net.sf.proguard" name="proguard" rev="4.11" conf="build">
<artifact name="proguard" ext="jar"/>
</dependency>
</dependencies>
</ivy-module>
When I come to depend on this module in another project I specify the compile configuration but get told by IvyDE that compile does not exist.
<?xml version="1.0" encoding="ISO-8859-1"?>
<ivy-module version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd">
<info
organisation="org"
module="module2"
status="integration">
</info>
<configurations>
<conf name="compile" description="Default required to compile the full module" />
</configurations>
<dependencies>
<dependency transitive="true" org="org" name="module" rev="latest.integration" conf="compile">
<artifact name="module" type="jar" ext="jar" />
<artifact name="module-src" type="source" ext="zip" />
<artifact name="module-doc" type="doc" ext="zip" />
</dependency>
</dependencies>
</ivy-module>
With this setup I get the error message
"configuration not found in org#module;0.277-SNAPSHOT: 'compile'"
I do get the jar if the dependency conf is updated to compile->* but I don't get the source or javadoc downloaded unless they are explicitly defined as dependencies. I am also expecting that junit will appear on the build path as it is defined as a compile dependency but there is no sign of that appearing while it doesn't know what the compile configuration is I guess.
Any suggestions please!
It seems the reason for this was Ivy not finding the ivy in artifactory correctly. Using a URL resolver rather than a ibiblio resolver and defining the ivy pattern everything is working correctly.

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.

Publish Only Dependencies

I want to publish the dependencies of a module seperately from the jar artifact of the module.
<?xml version="1.0" encoding="UTF-8"?>
<ivy-module version="2.0">
<info organisation="com.mycompany" module="platform" />
<configurations defaultconfmapping="release->*;compile->*" defaultconf="release">
<conf name="release" />
<conf name="compile" extends="release" />
</configurations>
<publications>
<artifact name="platform-api" type="jar" ext="jar" />
</publications>
<dependencies>
<dependency org="com.google.inject" name="guice" rev="3.0" />
<dependency org="org.slf4j" name="slf4j-api" rev="1.6.6" />
<dependency org="com.google.guava" name="guava" rev="13.0-rc1" conf="compile" />
<dependency org="log4j" name="log4j" rev="1.2.17" conf="compile" />
<dependency org="org.slf4j" name="slf4j-log4j12" rev="1.6.6" conf="compile" />
</dependencies>
</ivy-module>
For the configuration above, I want an artifact that includes guice & slf4j-api jars only, without the platform-api.jar. My current solution is to define two dependencies in the dependent module, one transitive and other not:
<dependency org="com.mycompany" name="platform" rev="1.0-SNAPSHOT" conf="myconf->release">
<exclude org="com.mycompany" />
</dependency>
<dependency org="com.mycompany" name="platform" rev="1.0-SNAPSHOT" transitive="false" conf="myotherconf->release" />
But this solution causes problems when the third module is dependent on both of these modules, and it is just ugly.
Try this instead:
<ivy-module version="2.0">
<info organisation="com.mycompany" module="platform" />
<configurations>
<conf name="default" description="runtime dependencies and master artifact can be used with this conf" extends="runtime,master"/>
<conf name="master" description="contains only the artifact published by this module itself, with no transitive dependencies"/>
<conf name="compile" description="Compile dependencies"/>
<conf name="runtime" description="Runtime dependencies, includes compile dependencies" extends="compile"/>
</configurations>
<publications>
<artifact name="platform-api" type="jar" ext="jar" conf="master"/>
</publications>
<dependencies>
<!-- Compile dependencies -->
<dependency org="com.google.inject" name="guice" rev="3.0" conf="compile->default"/>
<dependency org="org.slf4j" name="slf4j-api" rev="1.6.6" conf="compile->default"/>
<dependency org="com.google.guava" name="guava" rev="13.0-rc1" conf="compile->default" />
<!-- Runtime dependencies -->
<dependency org="log4j" name="log4j" rev="1.2.17" conf="runtime->default" />
<dependency org="org.slf4j" name="slf4j-log4j12" rev="1.6.6" conf="runtime->default" />
</dependencies>
</ivy-module>
Notes:
Note the "extends" attribute on the configurations, used to create larger sets of jars.
I recommend remove the default configuration mapping and explicitly set a conf mapping on each depedency. Simpler and ultimately easier to understand in my opinion (less magic)
Now that your module has separate configurations for the published artifacts and it's runtime dependencies a single dependency declaration can be used as follows to map these to separate local configurations:
<dependency org="com.mycompany" name="platform" rev="1.0-SNAPSHOT" conf="myconf->runtime;myotherconf->master" />
I think, what you are looking for is actually two projects sharing the same dependencies. (and by coincidence one of them is using the other as well).
Did you consider using extends http://ant.apache.org/ivy/history/latest-milestone/ivyfile/extends.html with:
extendType="dependencies".
Then you would have your platform extending the the parent-ivy.xml with the dependencies. And your Other project extending the same parent-ivy.xml file for the same dependencies.
I'm not sure if this is enough. Since the configurations will play role here. But maybe it's a start.

Spring Framework dependency not resolved in Ivy

I am trying to download Spring Batch and Spring Framework using Ivy, and I'm not getting very far.
Dependencies in ivy.xml:
<dependency org="org.springframework.batch" name="org.springframework.batch.core" rev="2.1.6.RELEASE" />
<dependency org="org.springframework" name="org.springframework.spring-library" rev="3.0.6.RELEASE" />
ivysettings.xml:
<ivysettings>
<settings defaultResolver="chained"/>
<resolvers>
<chain name="chained">
<url name="com.springsource.repository.bundles.release">
<ivy pattern="http://repository.springsource.com/ivy/bundles/release/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
<artifact pattern="http://repository.springsource.com/ivy/bundles/release/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
</url>
<url name="com.springsource.repository.bundles.external">
<ivy pattern="http://repository.springsource.com/ivy/bundles/external/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
<artifact pattern="http://repository.springsource.com/ivy/bundles/external/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
</url>
</chain>
</resolvers>
</ivysettings>
build.xml:
...
<ivy:settings file="ivysettings.xml"/>
...
<target name="resolve" description="retrieve dependencies with ivy">
<ivy:retrieve/>
</target>
When I run ant resolve I get the following:
[ivy:retrieve] ::::::::::::::::::::::::::::::::::::::::::::::
[ivy:retrieve] :: UNRESOLVED DEPENDENCIES ::
[ivy:retrieve] ::::::::::::::::::::::::::::::::::::::::::::::
[ivy:retrieve] :: org.springframework#org.springframework.spring-library;3.0.6.RELEASE: not found
[ivy:retrieve] ::::::::::::::::::::::::::::::::::::::::::::::
What am I doing wrong? I've used this page for getting the configuration.
Spring libraries are now published via Maven Central. This means they can be found using the Maven search website:
Spring Framework
Spring Batch
This means you need to declare your dependencies as follows:
<dependency org="org.springframework.batch" name="spring-batch-core" rev="2.1.8.RELEASE"/>
<dependency org="org.springframework" name="spring-core" rev="3.0.6.RELEASE"/>
A settings file now becomes optional (Maven Central is an ivy default).
If you want to create one, use the following:
<ivysettings>
<settings defaultResolver="central"/>
<resolvers>
<ibiblio name="central" m2compatible="true"/>
</resolvers>
</ivysettings>

Keep Ivy from including test dependencies

Consider an ivy.xml like the following:
<ivy-module version="2.0">
<info organisation="com.foo" module="FooBar" />
<dependencies>
<dependency org="net.sf.ehcache" name="ehcache-core" rev="2.2.0" />
<!--...-->
</dependencies>
</info>
</ivy-module>
When I run Ivy, it fetches all dependencies for EHCache, even testing dependencies. Specifically, it tries to pull in Hibernate 3.5.1 (which, in the POM file, is listed as a "test" dependency).
How do I prevent Ivy from including test dependencies? I could list it as an excluded dependency, but I don't want to have to do this for every test dependency. I'm new to Ivy and used to the way Maven does things. I was reading about configurations but I don't understand how this aspect of Maven's "scope" maps to "configurations."
You need to define the configuration of the dependency like:
<dependency org="net.sf.ehcache" name="ehcache-core" rev="2.2.0" conf="compile"/>
If you omit conf it is assumed, that you meant conf ="*", which will download all configurations for that dependency.
Here is a simple Example:
<configurations>
<conf name="test" visibility="public" />
<conf name="compile" visibility="public" />
</configurations>
<publications>
<artifact name="${project.name}" type="jar" conf="compile" ext="jar"/>
<artifact name="${project.name}-test" type="jar" conf="test" ext="jar"/>
</publications>
<dependencies>
<!-- COMPILE -->
<dependency org="log4j" name="log4j" rev="1.2.14" conf="compile->*"/>
<dependency org="apache" name="commons-net" rev="2.0" conf="compile->*"/>
<dependency org="itext" name="itext" rev="1.4.6" conf="compile->*"/>
<dependency org="jsch" name="jsch" rev="0.1.29" conf="test->*"/>
<!-- TEST -->
</dependencies>
In this example jsch will be included in the test and the compile configuration.
If you resolve this dependency later with conf ="compile" you will get all dependencies EXCEPT jsch.
If you resolve this dependency with conf ="test" you will get jsch only.
And if test would extend compile, you would get all jars.
<configurations>
<conf name="test" visibility="public" extends="compile" />
<conf name="compile" visibility="public" />
</configurations>