Ivy Use Cases

What is this page about?

This page demonstrate common and possible uses of Ivy. The main usage is of course bringing Java JAR files to a project but there may be other interesting use cases.

The most common use cases

The following use cases are very common and are going after Apache Maven's spirit.

  1. (The trivial one(smile) Find and bring Java JAR files needed to compile a Java project. (Known as "compile" dependency.)
  2. (Almost trivial as the above) Declare the runtime dependencies of a Java product in other Java JAR files. (Known as "runtime" dependency.)
  3. Find and bring Java JAR files needed for unit test, usually during an automatic build. (Known as "test" dependency.)

Note: these kind of dependencies (AKA 'configurations') are widely used by free open source projects around. Other kinds of dependencies are not standard and are used (or may be used) mostly internally by organizations.

Other possible and interesting use cases

  1. Web service WSDL versioning. The idea here is to create a project ('module') containing WSDL and probably XSD files needed to define a web-service. The need to version WSDL documents comes mainly during parallel development of a web-service and its client. They both depends on the WSDL document and have to explicitly know if they are using the same interface - the WSDL document. Note: This use case could be generalized as "interface versioning". It is good not only for WSDL but also to CORBA IDL, and alike.
  2. Build time properties. During the build, we often need to use common properties that are the same among all the projects. For example: we want to add Vendor-Name and Vendor-URL to the JAR manifest; or we want to auto-generate Java code from XML schema with a common set of XML-namespace-to-Java-package-name mapping. For such uses, we can create an ivy module that other projects depends on, and automatically share these properties in a simple way. This is better than just using a properties file that is located 'somewhere around' (or worst: a file that is being duplicated of each and every project) since we use versioning. Using ivy.xml you can instantly know what exact version of the properties file your module had been built against. This dependency, of course, need to be declared using a separate 'configuration' in ivy.xml, in order not to be confused with the 'compile' and 'runtime' configurations.
  3. Non-code dependencies XML Schema (XSD files) are one of the many other formats that let you import a file to another file. The problem starts when you have some common base artifacts that are being used by higher level artifacts. For example: you have XML schemas for the infrastructure, and you have application specific XML schema for every application. You want to import the common infrastructure XSD file into your application's XSD file. The assumption is that you don't want to duplicate code or use symbolic links. You want to know what exact version of the infrastructure you have imported to your XSD file. One possible solution (without using Ivy) is to add the version name to the XSD file, and to use that version-explicit file name in the 'import' element of the application's XSD file. But in such solution you stick to a fixed version and cannot benefit from the 'latest' features of Ivy. Ivy's way would be to create a separate module for the infrastructure XSD (same as in section 2.1) with its own ivy.xml, and a separate module (+ ivy.xml) for any application depending on it. The applications can define 'latest.<something>' in the 'rev' attribute and will automatically get the latest infrastructure XSD file. After publish, the ivy.xml would explicitly indicate what exact version of the infrastructure XSD has been used. If you are going to implement this technique, you will probably rich to the following problem: what path+filename to write in the 'import' element of the application XSD file.

For example: before you considered Ivy, you had in the same directory: infrastructure.xsd and app.xsd. app.xsd imports 'infrastructure.xsd' without any additional path info, since they are both at the same directory. Another application: 'super-app' want to import 'app.xsd' along with its dependencies (infrastructure.xsd). With duplication, you simple copy 'app.xsd' and 'infrastructure.xsd' to 'super-app' XSD directory. Let's see how Ivy can help.

With Ivy, you define in ivy.xml of 'app' a "schema" configuration pointing to 'infrastructure' module. To use it, you 'ivy:retrieve' the infrastructure.xsd file to 'schema/imported' directory of 'app' project. 'app' project's own schema called 'app.xsd' sits in 'schema/src' directory. Hence, in 'app.xsd' you import '../imported/infrastructur.xsd' file. Notice the relative path. In 'super-app' ivy.xml you define a configuration "schema" depends on 'app' module. The same 'ivy:retrieve' brings both 'infrastructure.xsd' and 'app.xsd' to 'schema/imported' of 'super-app' project tree. 'super-app' project's own schema sits in 'schema/src' as before and importing '../imported/app.xsd' that itself imports '../imported/infrastructure.xsd'.

See the Ivy magic? Using retrieve and relative path in XSD import, you can benefit Ivy's dependency management on XML Schema artifacts!

(Note: I'll be glad if someone would be able to rewrite this section in better words... (smile) easyproglife.)

Other use cases

Note: if you are using Ivy in a different way, please share us all. The benefit would be to all of us: we would better understand what other people expect Ivy to do, and we may together develop common 'usage patterns' to address common problems in a common, easy and simple way.

remarks by Andreas Sahlbach

IMHO Ivy has to fulfill two requirements:

  1. resolve (transitive) dependencies for my project
  2. help me to manage my repositories

1) will not work without 2). I need a controlled way to access my repositories. I need to be able to get stuff from repositories (dependencies, my own build results, information about resolves) and I need to be able to put stuff into repositories (again: dependencies and my build results). All this needs to be usable from ant, so that I can put it altogether in a neat ant script (for the "dressed apes" that are going to use my ant script at the end). Examples:

My $0.02 end here. (smile) Andreas Sahlbach