Hi Gilles,

I have been unsuccessful in changing my buildscript in order to have the ivysettings defined only once.

Am I doing something wrong, or should I raise Jira to change the behaviour of ivysetting/classpath?

Thanks,

Derek

Derek Baum wrote:
Hi,

Thanks for your response.

Are you suggesting:

1) if I satisfy the prerequisite, then I won't need my suggested patch, or
2) my patch will only work if the prerequisite is satisfied?

Assuming 1), I tried this, but when I didn't explicitly load ivysettings, a default was loaded instead and the build failed.

Here's my subant target for the example multi-project/build.xml:
  <target name="publish-all" depends="buildlist"
description="compile, jar and publish all projects in the right order">
    <subant target="publish" buildpathref="build-list">
      <propertyset>
        <propertyref name="ivy.loaded" />
      </propertyset>
    </subant>
  </target>

Here's the Ivy taskdef:

    <target name="load-ivy" unless="ivy.loaded">
        <property name="ivy.loaded" value="true"/>
        <echo message="Loading Ivy ..."/>
        <taskdef resource="org/apache/ivy/ant/antlib.xml"
                 uri="antlib:org.apache.ivy.ant"
                 loaderRef="ivyLoader"
                 classpath="${ivy.jar.file}"/>
        <ivy:settings file="${common.dir}/ivysettings.xml" />
    </target>

and here's the build output, notice the loading of default settings in new-ivy-version:

[multi-project]$ ant publish-all
Buildfile: build.xml

load-ivy:
     [echo] Loading Ivy ...

buildlist:
[ivy:buildlist] :: Ivy 2.0.0-rc1 - 20080916082609 :: http://ant.apache.org/ivy/ :: :: loading settings :: file = /Volumes/Users/derek/eclipse/Sigil/bld-ivy/test/multi-project/common/ivysettings.xml

publish-all:

clean-build:
[delete] Deleting directory /Volumes/Users/derek/eclipse/Sigil/bld-ivy/test/multi-project/projects/version/build

load-ivy:

ivy-new-version:
No ivy:settings found for the default reference 'ivy.instance'. A default instance will be used
no settings file found, using default...
:: loading settings :: url = jar:file:/opt/apache-ivy-2.0.0-rc1/ivy-2.0.0-rc1.jar!/org/apache/ivy/core/settings/ivysettings.xml

version:
[mkdir] Created dir: /Volumes/Users/derek/eclipse/Sigil/bld-ivy/test/multi-project/projects/version/build/classes

I therefore had to change the load-ivy target to always define ivysettings:

   <target name="load-ivy" depends="ivy-taskdef">
       <ivy:settings file="${common.dir}/ivysettings.xml" />
   </target>

which is why I concluded that a change to the ivysettings/classpath command was needed.

Thanks,

Derek



Gilles Scokart wrote:
There will be a prerequisite for that to work : You must be sure that
that ivy itself is not loaded in two ClassLoader.  For that, your
taskdef for ivy should itself use a loaderRef, and the subant must
have the right options that make the id shared accross the projects.

And if that prerequisite is valid, in most case you can arrange your
buildscript in order to have the ivysettings defined only once.



2008/10/16 Derek Baum <[EMAIL PROTECTED]>:
Hi,

I have a custom Ivy resolver that keeps a static cache because it is
time-consuming to initialise.

However, this cache doesn't work in a multi-project build, because the
ivysettings/classpath command is creating a new URLClassLoader for each
subant iteration, so all static class fields are reset.

<ivysettings>

 <classpath file="${ivy.settings.dir}/sigil-ivy-plugin.jar" />

<typedef name="sigil" classname="org.cauldron.bld.ivy.SigilResolver" />

 ...

</ivysettings>


I'm building multiple projects, using ivy:buildlist and subant, as in the
Ivy multi-project example.

Each iteration of subant, causes IvySettings to reload.
IvySettings.classloader is thus null and so a new URLClassLoader is created.

I temporarily worked around this by loading my plugin at the same time as
Ivy (i.e. not using settings/classpath), but I'd really like the
setting/classpath method to work too.

One possible solution would be to add a "loaderRef" attribute to
settings/classpath, similar to the Ant taskdef/typedef tasks, to make it use
the same ClassLoader.

Alternatively, IvySettings could simply be changed to only create a new
URLClassLoader if the list of URLs has changed. I attach a simple patch to
IvySettings.java that does this and seems to work OK.

If this is valid and useful, let me know and I'll raise it in Jira.

Thanks,

Derek














Index: src/java/org/apache/ivy/core/settings/IvySettings.java
===================================================================
--- src/java/org/apache/ivy/core/settings/IvySettings.java (revision
705243)
+++ src/java/org/apache/ivy/core/settings/IvySettings.java (working
copy)
@@ -644,13 +644,19 @@
        }
    }

+    private static Map loaderCache =  new HashMap();
+
    private ClassLoader getClassLoader() {
        if (classloader == null) {
            if (classpathURLs.isEmpty()) {
                classloader = Ivy.class.getClassLoader();
            } else {
-                classloader = new URLClassLoader((URL[]) classpathURLs
+ classloader = (ClassLoader) loaderCache.get(classpathURLs);
+                if (classloader == null) {
+ classloader = new URLClassLoader((URL[]) classpathURLs
                        .toArray(new URL[classpathURLs.size()]),
Ivy.class.getClassLoader());
+                    loaderCache.put(classpathURLs, classloader);
+                }
            }
        }
        return classloader;


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]





---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to