On 5/10/07, Jarosław Wypychowski <[EMAIL PROTECTED]> wrote:
Hello,
Thanks for quick reply.
Dnia 10-05-2007, czw o godzinie 09:12 +0200, Xavier Hanin napisał(a):
> Well, I think we'd need more information about your build itself. As you
> have noticed, the context is attached to a thread local, but ant doesn't
> create threads that often. So maybe this is due to the way you call Ivy
(and
> this is a bug in any case, but I'm just trying to narrow the problem).
I did some more research (dumping Thread.currentThread(),
IvyContext.getContext() and IvyContext.getContext().get(IvyTask.ANT...)
at miscellaneous places and narrowed it to the WeakReference keeping the
Project in the IvyContext._contextMap. As for Threads - all was going on
in a single thread.
OK, so not a Thread but a WeakReference problem. Interesting. And that's why
the problem is occuring in an undeterministic way, because it's related to
when the GC is called.
IvyContext{
...
public Object get(String key) {
WeakReference ref = (WeakReference) _contextMap.get(key);
// System.out.println("ICTX GET "+key+" | "+ref
+"|"+Thread.currentThread()+"|"+this);
return ref == null ? null : ref.get();
}
...
}
With comment turned off the WeakReference is dead sometimes (though it
shouldn't be as the Ant Project for sure is still accessible by the main
Ant process).
Indeed, this is really weird, since we do not leave the ant build.
With comment turned on the WeakReference is alive when it
is expected to be alive and everything passes smoothly.
Funny thing is that adding a comment in the getContext() new context
creation block also helps.
Yes, this is strange too, but it might be side effect on the GC only, GC
calls are not predictable, it may happen that it just change the memory
consumption.
I'm not sure whether this is a problem with jvm or something else. The
WeakReference seems like a good idea to me for keeping Project, though
it might be stored directly with
Ivy*(IvyTask){
...
execute(){
setProjectInContext
realwork
unsetProjectInContext
}
...
}
Unless there are things in the background of Ivy that last past the
execute task and we need it to be Ant project aware.
No, nothing like that. For the ant project we can do something like this,
it's pretty easy because we are in control of all Ivy tasks, and clearly
know all entry points. We could do that by refactoring ivy tasks like that:
IvyTask {
execute() {
setProjectInContext
doExecute();
unsetProjectInContext
}
abstract doExecute();
}
then in all Ivy tasks we can rename execute to doExecute, when we're done.
The problem is that it will be very difficult to add a unit test for this
bug, since we do not really understand why the reference is lost. But at
least you are able to reproduce the problem, so maybe you would be the best
person to implement this fix, test it and submit a patch? :-)
Xavier
What did you change in your own ivy version?
Added a random comment. But now it is more predictable.
> BTW, did you try with Ivy 1.4.1? We have done quite a lot of refactoring
in
> Ivy 2.0, and it would help to know if it was working before or not.
No - and as for now it seems to me like no Ivy problem.
As for my build:
structure of the project:
lib/
#static repository in the SVN
build/
#local ivy cache
#temporary repo for integration things
yadda-common/trunk/
# subproject with no internal deps
yadda-services/trunk/
# subproject with yadda-commmon as internal dep
DeskLight/trunk
#project with yadda-services as internal dep.
ivysettings:
<ivysettings>
<!-- <properties file="build.properties"/>-->
<settings defaultResolver="yadda" defaultCache="${ivy.cache.dir}"/>
<triggers>
<ant-call target="trigger" event="pre-resolve-dependency"
prefix="event."/>
</triggers>
<resolvers>
<chain name="yadda">
<filesystem name="local">
<ivy
pattern="${ivy.repo.dir
}/[organisation]/[module]/ivys/ivy-[revision].xml"/>
<artifact
pattern="${ivy.repo.dir
}/[organisation]/[module]/[type]s/[artifact]-[revision].[type]"/>
</filesystem>
<filesystem name="libraries">
<artifact
pattern="${yadda.lib.repo}/bin/[artifact]-[revision].[ext]" />
</filesystem>
</chain>
</resolvers>
</ivysettings>
target trigger in both DeskLight and yadda-services:
<target name="trigger" depends="init">
<var name="ivy.revision" unset="true"/>
<var name="revision" unset="true"/>
<ivy:findrevision organisation="${event.organisation}"
module="${event.module}" revision="${event.revision}"
property="revision"/>
<if>
<not><isset property="revision"/></not>
<then>
<echo message="BUILDING"/>
<delete>
<fileset dir="../lib">
<include name="${module}-*"/>
</fileset>
</delete>
<ant dir="${root.dir}/${event.module}/trunk/build/"
antfile="build.xml" target="${event.module}.publish"
inheritall="false">
<property name="mode" value="local"></property>
</ant>
</then>
<else>
<echo message="found revision for ${event.module} :
${revision}"/>
</else>
</if>
</target>
and the publication task depends on standard resolve,retrieve - and
therefore is recursive from the point of view of build.
Best Regards.
--jw
--
Jaroslaw Wypychowski
Interdyscyplinarne Centrum Modelowania Matematycznego i Komputerowego UW
[EMAIL PROTECTED]
--
Xavier Hanin - Independent Java Consultant
Manage your dependencies with Ivy!
http://incubator.apache.org/ivy/