Bug 206732 - [itds] Problem with ITDs appearing to be applied twice (and clashing) for binary types
Summary: [itds] Problem with ITDs appearing to be applied twice (and clashing) for bin...
Status: RESOLVED FIXED
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: DEVELOPMENT   Edit
Hardware: Macintosh Mac OS X - Carbon (unsup.)
: P2 major (vote)
Target Milestone: 1.5.4   Edit
Assignee: Andrew Clement CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-10-18 05:54 EDT by Andrew Clement CLA
Modified: 2007-11-07 04:15 EST (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Andrew Clement CLA 2007-10-18 05:54:26 EDT
As reported by Josh on the mailing list:

I have the following 2 files:

 

Advised.aj:

 

package bugs;

 

public class Advised {}

aspect ITD {

          public void Advised.f() {}

}

 

Ref.aj:

 

package notbugs;

 

import bugs.Advised;

 

public class Ref {

          public void g() {

                   new Advised().f();

          }

}

 

I am attempting to build Advised.aj into a jar, and refer to it from Ref.aj, using the following ant build.xml:

 

<?xml version="1.0"?>

 

<project name="Bugs" basedir="C:\workplace\imds\Bugs"

          xmlns:aj="antlib:org.aspectj">

          <taskdef uri="antlib:org.aspectj" resource="org/aspectj/antlib.xml" classpath="./aspectjtools.jar"/>

          <target name="clean">

                   <delete dir="bugs" includes="**/*.class"/>

                   <delete dir="notbugs" includes="**/*.class"/>

          </target>

          <target name="task1">

                   <aj:iajc srcdir="." destdir="." source="1.5" target="1.5">

                             <classpath location=".\aspectjrt.jar"/>

                             <include name="bugs/Advised.aj"/>

                   </aj:iajc>

          </target>

          <target name="task2">

                   <aj:iajc source="1.5" target="1.5" srcdir=".">

                             <classpath location=".\aspectjrt.jar"/>

                             <aspectpath location="."/>

                             <include name="notbugs/Ref.aj"/>

                   </aj:iajc>

          </target>

</project>

 

From within Eclipse, there are no build errors because this is all one project.  On the command line, however, once I execute “ant task2”, I get the following marvelous error message which suggests that ajc is trying to ITD f into a class it already ITDd f into before:

 

  [aj:iajc] error at C:\workplace\imds\Bugs\bugs\Advised.aj:5::77 inter-type declaration from bugs.ITD conflicts with existing member: void bugs.Advised.f()

  [aj:iajc] MessageHolder:  (8 info)  (1 error)

  [aj:iajc] [error   0]: error at C:\workplace\imds\Bugs\bugs\Advised.aj:5::77 inter-type declaration from bugs.ITD conflicts with existing member: void bugs.Advised.f()

 

Let me also say that in my real use-case, the jar produced by task1 will contain aspects that should apply to clients thereof, and as such, that jar should indeed be in the aspectpath (not the classpath) for task2 (unless I am seriously misunderstanding something).

 

How to stop this duplicate attempt to ITD?

 

Josh

---

Josh is correct that using aspectpath will pull in the aspects for application to other types, the problem is that when pulling in type Advised, we reapply known ITDs and it clashes with the one added in the original build of the type.

Two possible fixes that I am looking at:
- don't reapply the ITDs (they are added to ensure type system is consistent) to binary types pulled in from the aspectpath
- recognize the ITD is clashing with a member previously applied through the same ITD

I am not sure we can determine it came from the aspectpath at the point the clash is detected.  I have option (2) already implemented, but I'll try a little more with option 1 before giving up ;)
Comment 1 Joshua Caplan CLA 2007-10-19 12:26:42 EDT
I think option 2 makes more sense anyway.

It seems to me that the end result of building 1 jar or n jars should be the same as long as I use aspectpath instead of classpath.  I'm thinking in particular of the case where A.jar contains ITDs that would apply to B.jar, and C.aj uses classes from B.jar as if they were woven with A.jar.  Now it appears that option 1 would preclude a build like

          <target name="C">
                   <aj:iajc source="1.5" target="1.5" srcdir=".">
                             <classpath location=".\aspectjrt.jar"/>
                             <aspectpath path="A.jar:B.jar"/>
                             <include name="C.aj"/>
                   </aj:iajc>
          </target>

whereas option 2 would just work.
Comment 2 Andrew Clement CLA 2007-10-20 19:34:18 EDT
Option 2 is fixed in the codebase now, just having trouble releasing it as cruisecontrol is playing up.

Option 2 would just work for your scenario - but I worry that if you forget to weave B.jar, then C will crash at runtime.  When we could have put out an error when compiling C that reminded you that you should have woven B.jar.  Is there some circular dependency scenario you are thinking of that meant the jars could not be woven in a logical order?
Comment 3 Andrew Clement CLA 2007-10-24 11:30:57 EDT
the latest download on the dev page includes the fix! hurray.
Comment 4 Andrew Clement CLA 2007-11-07 04:15:33 EST
going to mark as fixed now - gotta get it off my list of things to do for 1.5.4