I think I have a potential workaround. Instead of using the Ivy settings that the Ant project is aware of, construct a new IvyAntSettings object that's essentially a copy of the existing one. IvyAntSettings is a fairly involved class, so I'm not so sure that will work. Perhaps someone has had experience with pulling this off.
P.S. This is a case where the error message from Ivy is actually quite helpful: C:\...\build.xml:23: ivy.instance.for.tasks has been defined in a different classloader. Please use the same loader when defining your task, or redeclare your ivy:settings in this classloader For now, I'm following the advice, "or redeclare your ivy:settings in this classloader." On Thu, Jan 22, 2009 at 8:12 AM, Mitch Gitman <[email protected]> wrote: > Actually, let me try restating this query as a simpler question. Has anyone > tried writing their own Ant task that consumes the Ivy API? If so, what > decisions did you make as to the classpath location of the Ivy JAR and your > task's JAR so that it would work? Thanks. > > > On Wed, Jan 21, 2009 at 9:51 PM, Mitch Gitman <[email protected]> wrote: > >> 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}" /> >> >> >
