Apache Ivy resolve dependencies using Eclipse workspace during Ant build
Asked Answered
J

1

6

I'm using Apache Ivy with Eclipse (IvyDE) and trying to solve the following issue. I have two projects, IvyParent and IvyChild, where the child depends on the parent. I have the option selected for Eclipse Ivy Classpath Container to "Resolve dependencies in workspace".

The Eclipse autobuilder is working great - I get all my Ivy dependencies downloaded and included. I have both the parent and child projects open and I can make realtime edits to the parent and see the compilation changes in the child.

The problem is when I try to use Ant to build the child project into a jar. My question is, how can I leverage the Workspace resolver during an explicit Ant build?

I've looked into Ivy filesystem resolvers, but what I'm trying to avoid is having to Ant rebuild the parent project explicitly before Ant building the child.

The error I get is the following:

[ivy:retrieve] :: problems summary ::
[ivy:retrieve] :::: WARNINGS
[ivy:retrieve]      module not found: org.example#ParentModule;latest.integration
[ivy:retrieve]  ==== local: tried
[ivy:retrieve]  ...
[ivy:retrieve]  ==== shared: tried
[ivy:retrieve]  ...
[ivy:retrieve]  ==== public: tried
[ivy:retrieve]  ...
[ivy:retrieve]      ::::::::::::::::::::::::::::::::::::::::::::::
[ivy:retrieve]      ::          UNRESOLVED DEPENDENCIES         ::
[ivy:retrieve]      ::::::::::::::::::::::::::::::::::::::::::::::
[ivy:retrieve]      :: org.example#ParentModule;latest.integration: not found
[ivy:retrieve]      ::::::::::::::::::::::::::::::::::::::::::::::

BUILD FAILED
C:\Users\user\workspace\IvyExampleChild\build.xml:15: impossible to resolve dependencies:
    resolve failed - see output for details

Here is the parent project ivy.xml:

<?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.example" module="ParentModule" status="integration" />
    <dependencies>
        <dependency org="commons-lang" name="commons-lang" rev="2.6"/>
    </dependencies>
</ivy-module>

Here is the child project ivy.xml:

<?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.example" module="ChildModule" status="integration" />
    <dependencies>
        <dependency org="org.example" name="ParentModule" rev="latest.integration"/>
    </dependencies>
</ivy-module>

Here is the child build.xml:

<project xmlns:ivy="antlib:org.apache.ivy.ant" name="ChildModule" default="release">    
    <property name="build.dir" value="build" />
    <property name="build.dir.classes" value="${build.dir}/classes" />

    <property name="src.dir" value="src" />
    <property name="output.jar" value="${build.dir}/${ant.project.name}.jar" />

    <target name="clean">
        <delete includeemptydirs="true" quiet="true">
            <fileset dir="${build.dir}" />
        </delete>
    </target>

    <target name="apache-ivy" depends="clean">
        <ivy:retrieve />
        <ivy:cachepath pathid="ivy.build.path" conf="default" />
    </target>

    <target name="release" depends="apache-ivy">
        <echo message="compiling ${src.dir}..." />

        <mkdir dir="${build.dir}" />
        <mkdir dir="${build.dir.classes}" />

        <javac srcdir="${src.dir}" destdir="${build.dir.classes}" classpathref="ivy.build.path"/>
        <jar destfile="${output.jar}" basedir="${build.dir}"/>
    </target>
</project>
Joelynn answered 22/3, 2013 at 0:22 Comment(0)
G
4

This is a resolver and publishing problem. Your build for your ParentModule needs to 'publish' its jar to a specific directory. Then your child module build should be using a resolver that can find this specific directory.

So.. for example, ivy_settings might look like:

<ivysettings>
  <properties file="./ivysettings.properties"/>
  <property name="repository.dir" value="${ivy.build.dir}/repository"/>
  <settings defaultResolver="chain"/>
  <resolvers>
    <chain name="chain">
      <filesystem name="internal">
        <ivy pattern="${repository.dir}/[module]/ivy.xml" />
        <artifact pattern="${repository.dir}/[module]/[artifact].[ext]" />
      </filesystem>
      <ibiblio name="maven2" m2compatible="true"/>
    </chain>
  </resolvers>
</ivysettings>

and your build.xml files should have

  <ivy:settings file="${ivy.build.dir}/ivysettings.xml" />

What's happening here is we're telling ivy about a directory (...../repository) for the locally build jar files.

So your parent build now has in it's build.xml a 'publish' target:

<target name="publish" depends="jar, jarSources" description="--> publish this project in the ivy repository">
  <delete file="${dist.dir}/lib/ivy.xml"/>
  <ivy:publish artifactspattern="${dist.dir}/lib/[artifact](-[classifier]).[ext]"
          resolver="internal"
          status="integration"
          overwrite="true"/>
  <echo message="project ${ant.project.name} integration published" />
</target>

So.. run that and confirm your ParentModule.jar file shows up in your repository directory.

Once there, your child module should be able to 'resolve' your parent module jar file.

Gagliardi answered 25/4, 2013 at 23:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.