Apache

Overview

The sigil-ivy-plugin integrates Sigil with Apache Ivy. If you are not familiar with Ivy, you should visit their tutorial.

Sigil provides a custom Ivy resolver, which allows Ivy to resolve dependencies specified as OSGi Package-Imports, rather than as specific jar artifacts. This avoids the duplication and possible error of having to specify build dependencies separately from OSGi runtime dependencies.

The plugin works by intercepting the ivy.xml parser and dynamically replacing any dependencies with the results of resolving the OSGi Package-Imports specified in sigil.properties. Sigil can resolve dependencies using a local directory of OSGi bundles, or using an OBR repository.

The plugin also provides an Ant task to generate (multiple) OSGi bundles from each sigil.properties file using Bnd. sigil.properties is similar to .bnd instruction files, but it supports multiple bundles.

This Quick Start is based on the Ivy project dependencies tutorial, modified to use Sigil. The modified example is in example/dependence in the Sigil download.

Shared Configuration

ivysettings.properties

You will need to change ivy.jar to point to the location of your Ivy jar. If you don't have Ivy, you can download it from http://ant.apache.org/ivy/download.cgi.

repository.dir=${ivy.settings.dir}/repository
sigil-ivy-plugin.jar=${ivy.settings.dir}/../../../lib/sigil-ivy-plugin.jar
ivy.jar=/opt/apache-ivy-2.0.0-rc2/ivy-2.0.0-rc2.jar

ivysettings.xml

The lines containing "sigil" need to be added to your ivysettings.xml:

<ivysettings>
    <properties file="${ivy.settings.dir}/ivysettings.properties"/>
    <settings defaultResolver="projects"/>
    <caches defaultCacheDir="${ivy.settings.dir}/ivy-cache" />

    <classpath file="${sigil-ivy-plugin.jar}" />
    <typedef name="sigil-parser" classname="org.cauldron.bld.ivy.SigilParser" />
    <typedef name="sigil-resolver" classname="org.cauldron.bld.ivy.SigilResolver" />

    <parsers>
        <sigil-parser/>
    </parsers>

    <resolvers>
        <sigil-resolver name="sigil" config="${ivy.settings.dir}/sigil-repos.properties" />
        <filesystem name="projects">
            <artifact pattern="${repository.dir}/[artifact]-[revision].[ext]" />
            <ivy pattern="${repository.dir}/[module]-[revision].xml" />
        </filesystem>
    </resolvers>

    <modules>
        <module organisation="sigil" name="*" resolver="sigil"/>
    </modules>
</ivysettings>

sigil-repos.properties

This file contains the definition of the Sigil repositories. It is referenced via the config attribute on the sigil-resolver in ivysettings.xml.

The repositories defined are:

It's also possible to define a filesystem repository based on a local directory containing bundles.

# repository config

-repositories:  system, project, spring

system;provider:        system
system;level:           -1

project;provider:       project
project;level:  0
project;pattern:        ../*/[sigilproject]

spring;provider:        obr
spring;level:           2
spring;url:             http://sigil.codecauldron.org/spring-repository.obr
spring;index:           ../settings/spring-repository.obr

Project Configuration

build.xml

The sigil-ivy-plugin provides an Ant task to build bundles using Bnd. It requires bndlib.jar, which is on the manifest Class-Path, so you don't need to explicitly add bndlib.jar to the classpath, as long as it is present in the same directory as sigil-ivy-plugin.jar.

<taskdef name="sigil.bundle"
    classname="org.cauldron.bld.ant.BundleTask"
    classpath="${sigil-ivy-plugin.jar}"/>

<target name="jar" depends="compile">
    <sigil.bundle destpattern="${build.dir}/[id].[ext]"
                 classpathref="run.path.id" />
</target>

ivy.xml

The ivy.xml for the dependee project is unchanged (but, by default, Sigil ignores any dependences it contains).

<ivy-module version="1.0">
    <info organisation="org.apache" module="dependee"/>
    <dependencies>
        <dependency org="commons-lang" name="commons-lang" rev="2.0"/>
    </dependencies>
</ivy-module>

sigil.properties

Placing a sigil.properties file next to an ivy.xml file, causes the sigil-parser to dynamically replace the dependencies contained in ivy.xml with dependencies determined from the -imports property in sigil.properties.

# dependee sigil.properties

version: 1.0.0

-bundles: dependee

-exports: standalone

-imports: \
  org.apache.commons.lang;version="[2.0.0,2.4.0)", \

-resources: \
  version.properties

Project Build

$ cd dependee
$ ant jar
Buildfile: build.xml

init:

resolve:
[ivy:retrieve] :: Ivy 2.0.0-rc2 - 20081028224207 :: http://ant.apache.org/ivy/ ::
:: loading settings :: file = /Volumes/Users/derek/sigil-0.7.0/example/dependence/settings/ivysettings.xml
[ivy:retrieve] Sigil: augmenting module=dependee ant.project.name=dependee
[ivy:retrieve] Sigil: loading Project Repository: /Volumes/Users/derek/sigil-0.7.0/example/dependence/*/sigil.properties
[ivy:retrieve] :: resolving dependencies :: org.apache#dependee;working@rodney
[ivy:retrieve]  confs: [default]
[ivy:retrieve] Sigil: augmenting module=com.springsource.org.apache.commons.lang ant.project.name=dependee
[ivy:retrieve]  found sigil#com.springsource.org.apache.commons.lang;2.1.0 in sigil
[ivy:retrieve] downloading http://repository.springsource.com/ivy/bundles/external/org.apache.commons/
    com.springsource.org.apache.commons.lang/2.1.0/com.springsource.org.apache.commons.lang-2.1.0.jar ...
[ivy:retrieve]  [SUCCESSFUL ] sigil#com.springsource.org.apache.commons.lang;2.1.0!com.springsource.org.apache.commons.lang.jar (2619ms)
[ivy:retrieve] :: resolution report :: resolve 232ms :: artifacts dl 2620ms
        ---------------------------------------------------------------------
        |                  |            modules            ||   artifacts   |
        |       conf       | number| search|dwnlded|evicted|| number|dwnlded|
        ---------------------------------------------------------------------
        |      default     |   1   |   1   |   1   |   0   ||   1   |   1   |
        ---------------------------------------------------------------------
[ivy:retrieve] :: retrieving :: org.apache#dependee
[ivy:retrieve]  confs: [default]
[ivy:retrieve]  1 artifacts copied, 0 already retrieved (204kB/11ms)

compile:
    [mkdir] Created dir: /Volumes/Users/derek/sigil-0.7.0/example/dependence/dependee/build/classes
    [javac] Compiling 1 source file to /Volumes/Users/derek/sigil-0.7.0/example/dependence/dependee/build/classes

jar:
[propertyfile] Creating new property file: /Volumes/Users/derek/sigil-0.7.0/example/dependence/dependee/build/classes/version.properties
[sigil.bundle] creating bundle: dependee
[sigil.bundle] dependee: 0 errors, 0 warnings

BUILD SUCCESSFUL
Total time: 6 seconds

Notice how

-imports: \
  org.apache.commons.lang;version="[2.0.0,2.4.0)"

in sigil.properties is resolved to com.springsource.org.apache.commons.lang-2.1.0.jar, using the OBR resolver.

The dependencies in ivy.xml are ignored by default, you can retain them by setting the keepDependencies attribute on the sigil-parser.

Now let's pretend that we've added some code which requires the following imports in sigil.properties:

-imports: \
  org.apache.commons.lang;version="[2.0.0,2.4.0)", \
  javax.servlet;version="(2.4,3.0]", \
  org.apache.log4j;version="[1.2.14,1.3)", \
  org.apache.commons.logging
$ ant jar
Buildfile: build.xml

init:

resolve:
[ivy:retrieve] :: Ivy 2.0.0-rc2 - 20081028224207 :: http://ant.apache.org/ivy/ ::
:: loading settings :: file = /Volumes/Users/derek/sigil-0.7.0/example/dependence/settings/ivysettings.xml
[ivy:retrieve] Sigil: augmenting module=dependee ant.project.name=dependee
[ivy:retrieve] Sigil: loading Project Repository: /Volumes/Users/derek/sigil-0.7.0/example/dependence/*/sigil.properties
[ivy:retrieve] :: resolving dependencies :: org.apache#dependee;working@rodney
[ivy:retrieve]  confs: [default]
[ivy:retrieve] Sigil: augmenting module=com.springsource.org.apache.commons.logging ant.project.name=dependee
[ivy:retrieve]  found sigil#com.springsource.org.apache.commons.logging;1.1.1 in sigil
[ivy:retrieve] Sigil: augmenting module=com.springsource.org.apache.log4j ant.project.name=dependee
[ivy:retrieve]  found sigil#com.springsource.org.apache.log4j;1.2.15 in sigil
[ivy:retrieve]  found sigil#com.springsource.org.apache.commons.lang;2.1.0 in sigil
[ivy:retrieve] Sigil: augmenting module=com.springsource.javax.servlet ant.project.name=dependee
[ivy:retrieve]  found sigil#com.springsource.javax.servlet;2.5.0 in sigil
[ivy:retrieve] downloading http://repository.springsource.com/ivy/bundles/external/org.apache.commons/
    com.springsource.org.apache.commons.logging/1.1.1/com.springsource.org.apache.commons.logging-1.1.1.jar ...
[ivy:retrieve]  [SUCCESSFUL ] sigil#com.springsource.org.apache.commons.logging;1.1.1!com.springsource.org.apache.commons.logging.jar (3180ms)
[ivy:retrieve] downloading http://repository.springsource.com/ivy/bundles/external/org.apache.log4j/
    com.springsource.org.apache.log4j/1.2.15/com.springsource.org.apache.log4j-1.2.15.jar ...
[ivy:retrieve]  [SUCCESSFUL ] sigil#com.springsource.org.apache.log4j;1.2.15!com.springsource.org.apache.log4j.jar (5680ms)
[ivy:retrieve] downloading http://repository.springsource.com/ivy/bundles/external/javax.servlet/
    com.springsource.javax.servlet/2.5.0/com.springsource.javax.servlet-2.5.0.jar ...
[ivy:retrieve]  [SUCCESSFUL ] sigil#com.springsource.javax.servlet;2.5.0!com.springsource.javax.servlet.jar (1856ms)
[ivy:retrieve] :: resolution report :: resolve 562ms :: artifacts dl 10733ms
        ---------------------------------------------------------------------
        |                  |            modules            ||   artifacts   |
        |       conf       | number| search|dwnlded|evicted|| number|dwnlded|
        ---------------------------------------------------------------------
        |      default     |   4   |   3   |   3   |   0   ||   4   |   3   |
        ---------------------------------------------------------------------
[ivy:retrieve] :: retrieving :: org.apache#dependee
[ivy:retrieve]  confs: [default]
[ivy:retrieve]  3 artifacts copied, 1 already retrieved (534kB/50ms)

compile:

jar:
[propertyfile] Updating property file: /Volumes/Users/derek/sigil-0.7.0/example/dependence/dependee/build/classes/version.properties
[sigil.bundle] creating bundle: dependee
[sigil.bundle] BND: Importing packages that are never refered to by any class on the Bundle-Classpath[Jar:dot]: 
    [javax.servlet, org.apache.commons.logging, org.apache.log4j]
[sigil.bundle] dependee: 0 errors, 1 warning

BUILD SUCCESSFUL
Total time: 16 seconds

Notice that the additional dependencies have been resolved against the OBR repository. The warning from Bnd, is because those additional imports are not actually used.

Next Steps

This Quick Start has shown how easily Sigil can integrate with existing Ivy builds. You should now examine the other examples, which give more details of the Sigil configuration and show some real-world examples.

Last modified by dsavage@apache.org on 2009-07-13 13:41:35.0
Apache Felix, Felix, Apache, the Apache feather logo, and the Apache Felix project logo are trademarks of The Apache Software Foundation. All other marks mentioned may be trademarks or registered trademarks of their respective owners.