Bug 42482

Summary: ant and subant improperly passes references to macrodefs and scriptdefs to the child script
Product: Ant Reporter: Sandu Turcan <sanduatwork>
Component: Core tasksAssignee: Ant Notifications List <notifications>
Status: NEW ---    
Severity: normal    
Priority: P1    
Version: 1.7.0   
Target Milestone: ---   
Hardware: Other   
OS: other   
Attachments: Testcase to reproduce both bugs

Description Sandu Turcan 2007-05-21 19:19:16 UTC
I have created my own antlib that contains macrodefs and scripdefs. I reference
it using a namespace declaration. It works fine until I invoke my tasks from a
child script called by subant.
Invoking a scriptdef task results in "Script repository not found for ..."
thrown from ScriptDefBase.getScript.
Invoking a macrodef has another sideeffect.
If I have something like:
<macrodef name="mymacro>
<attribute name="basedir" default="${basedir}"/>
....
The default is being evaluated once for the parent script and then is passed
along to the child script.

I went throught the code and I think the problem is that
ComponentHelper.initSubProject passes all the custom typedefs and taskdefs to
the child script.
This works well with regular taskdefs and typedefs because they are essentialy
static, however scriptdefs and macrodefs are not. Well maybe only macrodefs -
the scriptdef issue seems to be just a bug.
Comment 1 Steve Loughran 2007-05-22 02:34:06 UTC
...I think I see what you are saying. The second time the antlib declaration is
encountered the antlib isnt re-evaluated, so the old defaults are retained.

Can you include the antlib.xml and full stack trace...this will help with
diagnostics. 

We'll have to think about what to do here.
Comment 2 rich 2011-01-26 07:05:45 UTC
I'm wondering if this issue has surfaced for me using Ant 1.8.2.  In my case, I also have an anlib with a scriptdef and I'm getting the same exception when running the script using AntUnit.  (I'm assuming, though haven't verified, that AntUnit is doing something akin to a subant to invoke the build targets.)

Is there any hope this can or will be fixed?

If needed I can try to create a (much) simplified example and attach it.
Comment 3 Stefan Bodewig 2011-01-26 10:44:29 UTC
a testcase would help a lot
Comment 4 rich 2011-01-28 21:47:02 UTC
(In reply to comment #3)
> a testcase would help a lot

Still trying to create a simple test case without any luck.  Can you give me some ideas of what could cause ScriptDefBase.getScript() to throw the "Script repository not found" exception?  That might help me narrow down a simple example.
Comment 5 rich 2011-01-31 07:45:09 UTC
(In reply to comment #4)
> Still trying to create a simple test case without any luck.  Can you give me
> some ideas of what could cause ScriptDefBase.getScript() to throw the "Script
> repository not found" exception?  That might help me narrow down a simple
> example.

OK, narrowed it down just a bit, but not enough to attach as a simple example.  The antlib containing the macrodef and scriptdef is bundled in a jar file, from which I can specify as the classpath in the taskdef.  This works fine in a normal build, but it breaks when I run it from antunit with this stack trace:

C:\dev\projects\ant-shared-build\src\main\resources\com\example\ant\sharedbuild\antlib.xml:40: Script repository not found for antlib:com.example.ant.sharedbuild:import
        at org.apache.tools.ant.taskdefs.optional.script.ScriptDefBase.getScript(ScriptDefBase.java:58)
        at org.apache.tools.ant.taskdefs.optional.script.ScriptDefBase.setDynamicAttribute(ScriptDefBase.java:92)
        at org.apache.tools.ant.IntrospectionHelper.setAttribute(IntrospectionHelper.java:394)
        at org.apache.tools.ant.RuntimeConfigurable.maybeConfigure(RuntimeConfigurable.java:388)
        at org.apache.tools.ant.RuntimeConfigurable.maybeConfigure(RuntimeConfigurable.java:344)
        at org.apache.tools.ant.Task.maybeConfigure(Task.java:202)
        at org.apache.tools.ant.UnknownElement.configure(UnknownElement.java:196)
        at org.apache.tools.ant.UnknownElement.maybeConfigure(UnknownElement.java:163)
        at org.apache.tools.ant.Task.perform(Task.java:347)
        at org.apache.tools.ant.taskdefs.Sequential.execute(Sequential.java:68)
        at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291)
        at sun.reflect.GeneratedMethodAccessor5.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
        at org.apache.tools.ant.Task.perform(Task.java:348)
        at org.apache.tools.ant.taskdefs.MacroInstance.execute(MacroInstance.java:398)
        at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291)
        at sun.reflect.GeneratedMethodAccessor5.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
        at org.apache.tools.ant.Task.perform(Task.java:348)
        at org.apache.tools.ant.Target.execute(Target.java:390)
        at org.apache.tools.ant.helper.ProjectHelper2.parse(ProjectHelper2.java:180)
        at org.apache.tools.ant.ProjectHelper.configureProject(ProjectHelper.java:82)
        at org.apache.ant.antunit.AntUnit.createProjectForFile(AntUnit.java:483)
        at org.apache.ant.antunit.AntUnit.doFile(AntUnit.java:231)
        at org.apache.ant.antunit.AntUnit.doResourceCollection(AntUnit.java:216)
        at org.apache.ant.antunit.AntUnit.execute(AntUnit.java:187)
        at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291)
        at sun.reflect.GeneratedMethodAccessor5.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
        at org.apache.tools.ant.Task.perform(Task.java:348)
        at org.apache.tools.ant.Target.execute(Target.java:390)
        at org.apache.tools.ant.Target.performTasks(Target.java:411)
        at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1399)
        at org.apache.tools.ant.Project.executeTarget(Project.java:1368)
        at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
        at org.apache.tools.ant.Project.executeTargets(Project.java:1251)
        at org.apache.tools.ant.Main.runBuild(Main.java:809)
        at org.apache.tools.ant.Main.startAnt(Main.java:217)
        at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280)
        at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109)

However, if instead of using the jar file as the taskdef classpath I use an exploded directory, then the tests run fine.

So, is there some interaction in classloading from a jar file and antlibs containing macrodefs and scriptdefs?
Comment 6 rich 2011-02-02 08:22:53 UTC
Got my answer, though it's a bit embarrassing:  The problem is I'm running my tests before creating the jar file, so of course trying to use the jar file in my classpath won't work.

In my defense I was led astray by the exception, because I didn't get the typical error about the typedef not being defined, etc.
Comment 7 Sandu Turcan 2011-02-02 09:58:07 UTC
Created attachment 26596 [details]
Testcase to reproduce both bugs