Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] STILL a compilation error with generics

#: Andy Clement changed the world a bit at a time by saying on  11/17/2005 10:41 AM :#
*sigh* we really should have handled this in a bug report given the
amount of mail its generating ... oh well.


1/ about org.aspectj\modules\tests\java5\generics\bugs\lists\case1:

The current CVS version of Bean and the aspect look:

[code]
public class Bean implements LongIdentifiable {

   public Long getId() {
     return null;
   }

   public void setId(Long t) {
   }

}

public aspect IdentifiableAspect {
     declare parents: Bean implements LongIdentifiable;

     private Long LongIdentifiable.m_id;

     public Long LongIdentifiable.getId() {
         return m_id;
     }

     public void LongIdentifiable.setId(Long id) {
         m_id= id;
     }

   public static void main(String []argv) {
     new Bean();
   }
}
[/code]

as far as I can say: this test case may be used only to proove that the aspect will not replace the
original methods in the bean. Is this the correct interpretation?

This tests that bridge methods are handled correctly - the testcase
revealed a problem with their creation which I fixed.


On the same scenario: try replacing the aspect main method with this main method:

[code]
     public static void main(String []argv) {
         Bean b = new Bean();
         b.setId(37L);
         long l = b.getId();
         if (l!=37L) throw new RuntimeException("id should be 37");
    }
[/code]

and you will have a surprize: a NPE thrown on the statement b.getId();

Its not surprising.  ITDs on interfaces provide a default
implementation that is picked up by an implementor of the interface
that doesn't provide their own version of those methods.  Bean
provides a version that returns null - so it doesn't get the ITD
versions and you get null.  You get the null at the b.getId() line
because getId() returns a 'Long' object and the variable is of type
'long' - the internal autoboxing call added by the compiler to unbox
the Long into a long blows up NPE.


2/ about org.aspectj\modules\tests\java5\generics\bugs\lists\case2:

The current CVS version of Bean and the aspect look:

[code]
public class Bean implements LongIdentifiable {
}

public aspect IdentifiableAspect {
     declare parents: Bean implements LongIdentifiable;

     private Long LongIdentifiable.m_id;

     public Long LongIdentifiable.getId() {
         return m_id;
     }

     public void LongIdentifiable.setId(Long id) {
         m_id= id;
     }

   public static void main(String []argv) {
     Bean b = new Bean();
     b.setId(37L);
     long l = b.getId();
     if (l!=37L) throw new RuntimeException("id should be 37");
   }
}
[/code]

With the AJ M5 and the AJDT incorporating it, the compilation of the above code failes with 2
reported errors:

Severity        Description     Resource        In Folder       Location        Creation Time   Id
2       can't override java.lang.Long org.noco.generics.LongIdentifiable.getId() with java.lang.Object
org.noco.generics.Bean.getId() return types don't match Bean.java
aj5_examples/src/main/org/noco/generics line 1  November 17, 2005 1:49:03 AM    27541

Severity        Description     Resource        In Folder       Location        Creation Time   Id
2       can't override java.lang.Long org.noco.generics.LongIdentifiable.getId() with java.lang.Object
org.noco.generics.Bean.getId() return types don't match IdentifiableAspect.aj
aj5_examples/src/main/org/noco/generics line 8  November 17, 2005 1:49:03 AM    27532

Doesnt look like the fix for these problems made it into M5.  Have you
tried compiling this program with the latest from HEAD?

Another thing is that the above code would be pretty strange:
- Bean declares as implementing the LongIdentifiable interface
- the aspect has a declare parents for the same thing

I put any testcase in the suite that demonstrates a failure -
regardless of how sensible it might be... you should see some of the
bizarre programs that are checked in ;)


3/ the correct scenario I am looking for is:

[code]
public class Bean {}

public aspect IdentifiableAspect {
     declare parents: Bean implements LongIdentifiable;

     private Long LongIdentifiable.m_id;

     public Long LongIdentifiable.getId() {
         return m_id;
     }

     public void LongIdentifiable.setId(Long id) {
         m_id= id;
     }

   public static void main(String []argv) {
     Bean b = new Bean();
     b.setId(37L);
     long l = b.getId();
     if (l!=37L) throw new RuntimeException("id should be 37");
   }
}
[/code]

In the same env (M5 and AJDT incorporating it), this fails exactly the same way it failed from the
beginning.

This demonstrates yet a *third* case of bridge methods causing a
problem - and I was silly not to spot that it could happen.  Because
the interface isn't on Bean from the beginning the binary weaving of
declare parents code that verifies rules about what can override what
was confused by a bridge method.  So, you will now find a 'case3' in
the tree and this is fixed too.

All 3 cases in the tree compile and run for me with the HEAD version
of the compiler.


I really hope we can get this issue solved soon, as my proof of concept is getting on the wrong
direction :-(.

The cases you've raised are exactly the kind of testing I want to see
of the generics support we have - and I thank you for that.  Generics
introduces a whole new range of possibilities and although we've added
1400 tests in AspectJ5 beyond what was in AspectJ1.2.1, there are many
more 1000s of testcases that could be written to exercise the compiler
and weaver.

There is a 'case4' of your program, but I'm not going to tell you what
it is until I have it working ;)

Andy.


But you probably forgot that I am updated, so I just can take a look ;-).

I will give a try with the CVS HEAD, and report it back.

thanks a lot,

./alex
--
.w( the_mindstorm )p.




Back to the top