Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apache Ivy resolve dependencies using Eclipse workspace during Ant build

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>
like image 805
earthbounce Avatar asked Mar 22 '13 00:03

earthbounce


People also ask

What is Ivy dependency management?

Ivy is a dependency manager -- it manages and controls the JAR files that your project depends on. If you don't have the JARs, it will pull them down for you by default (from the Maven 2 repository), which can make project setup a lot easier.

What is ivysettings?

The ivysettings. xml file holds a chain of Ivy resolvers for both regular artifacts and Ivy module files. These are used to resolve and publish (i.e. deploy) artifacts. There are a two ways to configure resolvers in ivysettings.


1 Answers

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.

like image 52
ticktock Avatar answered Oct 04 '22 03:10

ticktock