ant-ivy-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Mitch Gitman <mgit...@gmail.com>
Subject classpath issues: trying to consume Ivy API in an Ant task
Date Thu, 22 Jan 2009 05:51:29 GMT
I have a very, very simple Ant task that consumes the Ivy API. That is, in
the Java code for my Ant task, I'm using Ivy classes. One class I had been
trying to use was IvyAntSettings. Well, look what happened when I tried to
cast a reference I found in the Ant project to an actual IvyAntSettings
object. It's the telltale sign of ClassLoader issues: you can't cast a class
to itself:
BUILD FAILED
java.lang.ClassCastException: org.apache.ivy.ant.IvyAntSettings cannot be
cast to org.apache.ivy.ant.IvyAntSettings
        at org.myorg.ivy.IvyConsumerTask.execute(IvyConsumerTask.java:45)

It just so happened I realized I didn't need an IvyAntSettings instance, but
when I got rid of the IvyAntSettings cast, that just uncovered another
variation on the same ClassLoader problem:
BUILD FAILED
C:\...\build.xml:23: ivy.instance has been defined in a different
classloader.  Please use the same loader when defining your task, or
redeclare your ivy:settings in this classloader
        at org.apache.ivy.ant.IvyTask.getIvyInstance(IvyTask.java:82)
        at org.apache.ivy.ant.IvyTask.prepareTask(IvyTask.java:256)

Now, I can tell you what makes this problem go away, although it's a measure
I would just as soon NOT resort to. Put ivy.jar and the JAR for my Ant task
in one of Ant's primordial classloading directories:

   - ANT_HOME/lib
   - USER_HOME/.ant/lib

Here's a minimal Ant target where I'm able to reproduce my problem. In this
target, the Ivy JAR and my tasks JAR are in the directory templib:
  <target name="try-this">
    <property name="ivy.settings.url" value="
http://localhost/ivy/myorg/ivysettings.xml" />
    <property name="ivy.file" location="ivy.xml" />
    <path id="temp.myorg.tasks.classpath">
      <fileset dir="templib" includes="*.jar" />
    </path>
    <taskdef uri="antlib:org.apache.ivy.ant"
        resource="org/apache/ivy/ant/antlib.xml"
classpathref="temp.myorg.tasks.classpath" />
    <ivy:settings id="ivy.instance" url="${ivy.settings.url}" />
    <taskdef uri="antlib:org.myorg.tasks"
        resource="org/myorg/tasks/tasks.properties"
classpathref="temp.myorg.tasks.classpath" />
    <mynamespace:ivyconsumer
      conf="default"
      classpathid="some.classpath" />
  </target>

I suppose I could define the Ivy settings programmatically within my Ant
task, but I shudder at the implications of that. I'm afraid that, suddenly,
all use of Ivy has to go indirectly through my own Ant task, or additional
tasks. My question is, is there any way, short of the extreme measures I've
already described, to get my custom Ant task to use the same classloader as
was used by?:
    <ivy:settings id="ivy.instance" url="${ivy.settings.url}" />

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message