I am looking for the equivalent of a system scope dependency in Maven for Ivy. In Maven, declaring a dependency with system scope means that Maven will not include the dependency in the output, which is what I want. How can I achieve the same thing with Ivy?
2 Answers
I suspect you're talking about the Maven provided scope, not system.
provided This is much like compile, but indicates you expect the JDK or a container to provide the dependency at runtime. For example, when building a web application for the Java Enterprise Edition, you would set the dependency on the Servlet API and related Java EE APIs to scope provided because the web container provides those classes. This scope is only available on the compilation and test classpath, and is not transitive.
Ivy's configurations are very flexible which means that are several ways to do this.
ivy.xml
I would model my configuration on the different types of jar that my build will use:
<configurations>
<conf name="compile" description="Required to compile application"/>
<conf name="runtime" description="Additional run-time dependencies" extends="compile"/>
<conf name="test" description="Required for test only" extends="runtime"/>
<conf name="provided" description="Additional compile time dependencies, implementation provided by target platform"/>
</configurations>
The dependencies are then assigned to each logical grouping using a "conf" mapping:
<!-- compile dependencies -->
<dependency org="org.slf4j" name="slf4j-api" rev="1.7.5" conf="compile->default"/>
Note this is where the "extends" attribute it useful, without it the following mapping would be required for a logging dependency:
<!-- compile dependencies -->
<dependency org="org.slf4j" name="slf4j-api" rev="1.7.5" conf="compile,runtime,test->default"/>
Dependencies provided by the target platform are special. This is why I create a standalone configuration for them:
<!-- compile dependencies -->
<dependency org="my.target.platform" name="makeitgo-api" rev="1.0" conf="provided->default"/>
For even more details on ivy configuration mappings see:
build.xml
It's here where the classpaths are actually managed. (We could try and model the set relationships in various ivy configurations, but I'd argue this approach is simpler and gets the job done)
<target name="resolve" description="Use ivy to resolve classpaths">
<ivy:resolve/>
<ivy:report todir='${ivy.reports.dir}' graph='false' xml='false'/>
<ivy:cachepath pathid="compile.path" conf="compile,provided"/>
<ivy:cachepath pathid="test.path" conf="test,provided"/>
</target>
So just as the Maven documentation describes, add the provided dependencies to the compile and test path.
This means the "runtime" configuration only contains the dependencies that should be bundled:
<ivy:retrieve pattern="${build.dir}/WEB-INF/lib/[artifact]-[revision].[ext]" conf="runtime"/>

- 1
- 1

- 76,015
- 10
- 139
- 185
I guess that the only problem to deal with is to have a dependency which should be used at compile time but not at runtime, right ?
Here is an exemple of ivy.xml on how to deal with it:
<ivy-module version="2.0" xmlns:m="http://ant.apache.org/ivy/maven">
<info organisation="com.acme" module="mymodule" />
<configurations>
<conf name="default" description="runtime" />
<conf name="runtime" description="Runtime configuration"/>
<conf name="compile" description="Used only for compilation" />
<conf name="test" extends="compile,runtime" description="Unit testing configuration" visibility="private" />
</configurations>
<dependencies defaultconf="runtime,compile->default">
<!-- Compile and runtime -->
<dependency org="commons-lang" name="commons-lang" rev="2.6" />
<!-- Only compile -->
<dependency org="javax.servlet" name="servlet-api" rev="2.5" conf="compile->default" />
</dependencies>
</ivy-module>

- 2,014
- 1
- 15
- 14