ant-ivy-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Xavier Hanin" <xavier.ha...@gmail.com>
Subject Re: "ant call trigger can only be used from an ant build" from ant build
Date Thu, 10 May 2007 11:33:10 GMT
On 5/10/07, Jarosław Wypychowski <J.Wypychowski@icm.edu.pl> wrote:
>
> Fixed.
>
> I did found the source of problem - and the solution.
>
> The problem is in fact architectural.
>
> In my scenario there is a chain of events:
>
> ant->ivy:resolve->ant-call-trigger->ant->ivy:resolve->ant-call-trigger->ant->...
>
> The whole process is in a single Thread.
> so when we are in first ant-call - we override the parent Project
> settings. When we are in second - we override the parent Project. Ant
> build call creates a new project internally in execute of <ant/> task.
> So in the original scenario it would fail if the task already finished
> and GC cleaned the project. So the comment in my proposal was cleanly
> accidental in its help.
> Unfortunately going from WeakRef to direct save will not help either -
> as we will again override parent's project. There needs to be a complete
> change in the way the Project is kept within context.



You might not like my solution - so please tell me how it should look
> like to fit Your design.
>
> I've added specialized methods into the IvyContext:
>         public void setAntProject(Project project){
>                 List l=(List)_contextMap.get(
> IvyTask.ANT_PROJECT_CONTEXT_KEY);
>                 if(l==null){
>                         l=new ArrayList();
>                         _contextMap.put(IvyTask.ANT_PROJECT_CONTEXT_KEY,
> l);
>                 }
>                 l.add(0,project);
>         }
>
>         public void unsetAntProject(Project project){
>                 List l=(List)_contextMap.get(
> IvyTask.ANT_PROJECT_CONTEXT_KEY);
>                 if(l==null){
>                         return;
>                 }
>                 l.remove(project);
>         }
>
>         public void unsetAntProject(){
>                 List l=(List)_contextMap.get(
> IvyTask.ANT_PROJECT_CONTEXT_KEY);
>                 if(l==null){
>                         return;
>                 }
>                 l.remove(0);
>         }
>
>         public Project getAntProject(){
>                 List l=(List)_contextMap.get(
> IvyTask.ANT_PROJECT_CONTEXT_KEY);
>                 if(l==null || l.size()==0){
>                         return null;
>                 }
>                 return (Project)l.get(0);
>         }
>
>
> And modified get(String) into:
>
>         public Object get(String key) {
>                 if(IvyTask.ANT_PROJECT_CONTEXT_KEY.equals(key)) return
> getAntProject();
>                 if(_contextMap.get(key) instanceof WeakReference){
>                         WeakReference ref = (WeakReference)
> _contextMap.get(key);
>                         return ref == null ? null : ref.get();
>                 } else {
>                         return _contextMap.get(key);
>                 }
>         }
>
> Next I added doExecute as You suggested and made it stack a project on
> and off in the IvyTask.execute():
>     public void execute() throws BuildException {
>         IvyContext.getContext().setAntProject(getProject());
>         doExecute();
>         IvyContext.getContext().unsetAntProject(getProject());
>     }
>
>
> Now Projects are stacked during the execution of IvyTasks in single
> thread and removed when not needed anymore. Now all my tasks are going
> without errors.

Personally I don't really like the solution above (it mixes IvyTask with
> IvyContext) - so please suggest a better way.


Well, the problem of your solution is that it makes IvyContext depend on an
Ant class, which we have to avoid to keep Ivy core independent of Ant.

So I see two possible solutions:
* keep IvyContext as is, and set ANT_PROJECT_CONTEXT_KEY to a Stack instead
of a Project. In this case all classes dealing with ANT_PROJECT_CONTEXT_KEY
will have to be aware it's a Stack. Maybe adding a static method like
getCurrentProject() in IvyTask could centralize all the management of this
Stack.
* add methods to manage a Stack in IvyContext, because other classes may
have to deal with the same kind of problem. We could add a push, pop and
peek method, and use these methods instead of set and get from IvyTask,
AntCallTrigger and AntBuildTrigger.
Centralizing the management in IvyTask can make sense in either case. I have
a slight preference for the second one for its reusability, but it's only a
slight preference.

And If You would like me to finish the patch - what format of the patch
> would you like ? (diff params ?)


using regular svn diff is appropriate. Please create a JIRA issue for
attaching the patch, it's better to track the problem and to clear legal
issues while applying your patch (you have a box to check when attaching the
patch to allow us to apply it).

Thanks for your contribution!

Xavier


Best Regards
>
> --jw
>
> --
> Jaroslaw Wypychowski
> Interdyscyplinarne Centrum Modelowania Matematycznego i Komputerowego UW
> jarwyp@icm.edu.pl
>
>


-- 
Xavier Hanin - Independent Java Consultant
Manage your dependencies with Ivy!
http://incubator.apache.org/ivy/
Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message