You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by Nicolas Lalevée <ni...@hibnet.org> on 2012/09/16 16:21:37 UTC

Self-referencing Antlib limitation

I was still playing with classloaders and namespaces and antlib import with the AntDSL, and I encountered an unexpected limitation.

What I found: an antlib which is referencing itself in its definition cannot be loaded dynamically via an uri other than its antlib one.
This is the case for antunit:
<antlib xmlns:au="antlib:org.apache.ant.antunit">
[...]
  <taskdef name="fail"
    classname="org.apache.ant.antunit.AssertTask"/>
[...]
  <macrodef name="assertTrue" backtrace="false">
    <attribute name="message" default="Assertion failed"/>
    <element name="assertion" implicit="true"/>
    <sequential>
      <au:fail message="@{message}">
        <assertion/>
      </au:fail>
    </sequential>
  </macrodef>

And the following doesn't work:
<taskdef classpath="antunit.jar" uri="urn:antunit" resource="org/apache/ant/antunit/antlib.xml" />
(actually, this precise line works, but trying to use any antunit macro will fail)

I think that the issue is how Ant interpret the namespace declaration in the antlib definition. In Antunit:
<antlib xmlns:au="antlib:org.apache.ant.antunit">

When Ant is parsing it, it considers it as an antlib to be resolved later, whereas it should detect that this is the canonical uri of the antlib it is parsing, or sort of "this", and should use the uri actual used rather than the antlib one.

The behavior only affect cases where somebody is trying to load two different versions of the same antlib. This is some quite edge case, but do we agree this is an issue ?

I have committed a test case to see it in action. See r1385269. To run it, rename first broken_testURI to testURI in src/tests/antunit/taskdefs/taskdef-antlib-test.xml.

I had a quick look to how to fix it. As far I can tell, the best way to do it is to:
* in Definer.loadAntlib(ClassLoader, URL), make the createAntlib aware of the "resource" it was loaded from, and try to build an antlib uri from that.
* in Antlib.createAntlib(), let the projecthelper parse the file to an unknown element with the 'incorrect' uri. But then make a deep lookup in the tree of UnknownElements and change everything that needs to be changed.
It seems not trivial.
Let me know what you think.

Nicolas


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org


Re: Self-referencing Antlib limitation

Posted by Nicolas Lalevée <ni...@hibnet.org>.
Le 16 sept. 2012 à 18:03, Vimil Saju a écrit :

> Isn't it possible to use the "ant:current" uri to solve this issue, as described in the link below?
> 
> http://ant.apache.org/manual/Types/antlib.html 

Nice catch, I forgot about that. Probably antunit needs to be fixed.

But what about the antunit test I have committed disabled ? Should we consider it a valid use case ? Or should we consider a "bug" and promote the use of 'current' ?

I am in favor of the later, so we can avoid some tricky code.

Nicolas


> 
> 
> 
> ________________________________
> From: Nicolas Lalevée <ni...@hibnet.org>
> To: Ant Developers List <de...@ant.apache.org> 
> Sent: Sunday, September 16, 2012 7:21 AM
> Subject: Self-referencing Antlib limitation
> 
> I was still playing with classloaders and namespaces and antlib import with the AntDSL, and I encountered an unexpected limitation.
> 
> What I found: an antlib which is referencing itself in its definition cannot be loaded dynamically via an uri other than its antlib one.
> This is the case for antunit:
> <antlib xmlns:au="antlib:org.apache.ant.antunit">
> [...]
>   <taskdef name="fail"
>     classname="org.apache.ant.antunit.AssertTask"/>
> [...]
>   <macrodef name="assertTrue" backtrace="false">
>     <attribute name="message" default="Assertion failed"/>
>     <element name="assertion" implicit="true"/>
>     <sequential>
>       <au:fail message="@{message}">
>         <assertion/>
>       </au:fail>
>     </sequential>
>   </macrodef>
> 
> And the following doesn't work:
> <taskdef classpath="antunit.jar" uri="urn:antunit" resource="org/apache/ant/antunit/antlib.xml" />
> (actually, this precise line works, but trying to use any antunit macro will fail)
> 
> I think that the issue is how Ant interpret the namespace declaration in the antlib definition. In Antunit:
> <antlib xmlns:au="antlib:org.apache.ant.antunit">
> 
> When Ant is parsing it, it considers it as an antlib to be resolved later, whereas it should detect that this is the canonical uri of the antlib it is parsing, or sort of "this", and should use the uri actual used rather than the antlib one.
> 
> The behavior only affect cases where somebody is trying to load two different versions of the same antlib. This is some quite edge case, but do we agree this is an issue ?
> 
> I have committed a test case to see it in action. See r1385269. To run it, rename first broken_testURI to testURI in src/tests/antunit/taskdefs/taskdef-antlib-test.xml.
> 
> I had a quick look to how to fix it. As far I can tell, the best way to do it is to:
> * in Definer.loadAntlib(ClassLoader, URL), make the createAntlib aware of the "resource" it was loaded from, and try to build an antlib uri from that.
> * in Antlib.createAntlib(), let the projecthelper parse the file to an unknown element with the 'incorrect' uri. But then make a deep lookup in the tree of UnknownElements and change everything that needs to be changed.
> It seems not trivial.
> Let me know what you think.
> 
> Nicolas
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
> For additional commands, e-mail: dev-help@ant.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org


Re: Self-referencing Antlib limitation

Posted by Vimil Saju <vi...@yahoo.com>.
Isn't it possible to use the "ant:current" uri to solve this issue, as described in the link below?

http://ant.apache.org/manual/Types/antlib.html 



________________________________
 From: Nicolas Lalevée <ni...@hibnet.org>
To: Ant Developers List <de...@ant.apache.org> 
Sent: Sunday, September 16, 2012 7:21 AM
Subject: Self-referencing Antlib limitation
 
I was still playing with classloaders and namespaces and antlib import with the AntDSL, and I encountered an unexpected limitation.

What I found: an antlib which is referencing itself in its definition cannot be loaded dynamically via an uri other than its antlib one.
This is the case for antunit:
<antlib xmlns:au="antlib:org.apache.ant.antunit">
[...]
  <taskdef name="fail"
    classname="org.apache.ant.antunit.AssertTask"/>
[...]
  <macrodef name="assertTrue" backtrace="false">
    <attribute name="message" default="Assertion failed"/>
    <element name="assertion" implicit="true"/>
    <sequential>
      <au:fail message="@{message}">
        <assertion/>
      </au:fail>
    </sequential>
  </macrodef>

And the following doesn't work:
<taskdef classpath="antunit.jar" uri="urn:antunit" resource="org/apache/ant/antunit/antlib.xml" />
(actually, this precise line works, but trying to use any antunit macro will fail)

I think that the issue is how Ant interpret the namespace declaration in the antlib definition. In Antunit:
<antlib xmlns:au="antlib:org.apache.ant.antunit">

When Ant is parsing it, it considers it as an antlib to be resolved later, whereas it should detect that this is the canonical uri of the antlib it is parsing, or sort of "this", and should use the uri actual used rather than the antlib one.

The behavior only affect cases where somebody is trying to load two different versions of the same antlib. This is some quite edge case, but do we agree this is an issue ?

I have committed a test case to see it in action. See r1385269. To run it, rename first broken_testURI to testURI in src/tests/antunit/taskdefs/taskdef-antlib-test.xml.

I had a quick look to how to fix it. As far I can tell, the best way to do it is to:
* in Definer.loadAntlib(ClassLoader, URL), make the createAntlib aware of the "resource" it was loaded from, and try to build an antlib uri from that.
* in Antlib.createAntlib(), let the projecthelper parse the file to an unknown element with the 'incorrect' uri. But then make a deep lookup in the tree of UnknownElements and change everything that needs to be changed.
It seems not trivial.
Let me know what you think.

Nicolas


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org