Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] Inferred method having a generic as argument [ARGHHH SOLVED]

Hi Andy,
thanks again for taking the time to investigate.

The problem here is a bit different. I have only one interface, that
uses generics :

public interface Converter<T> {

And only one implementation of it :

public class IntegerConverter implements Converter<Integer> {

then I have a class, that does not uses generics, on which i want to add
a property and a method to add a converter. In java i can write :

public void setConverter(Converter converter);

OR

public void setConverter(Converter<?> converter);

OR

public <T> void setConverter(Converter<T> converter);

While in AspectJ the only possible way to write such a method is the
last one, using an unbound <T>; the other two will give a compilation
error when i try to invoke the method :

weavedclassinstance.setConverter(new IntegerConverter())

even if IntegerConverter is a Converter, is a Converter<?> and is a
Converter<T> with T unbound.

I don't know if there is a motivation for AspectJ to accept only the
last notation. Anyway this is quite difficult for a user to understand :)

Simone




Andy Clement wrote:
> If it is a just a generic method being declared on a target type, then
> the syntax is as you have:
>
> public <T> void TextComponent.setConverter(Converter<T> c) {
>
> If it is a method that will share the type variables (and thus any
> value they are bound to) with the target class then the syntax is:
>
> public void TextComponent<T>.setConverter(Converter<T> c) {
>
> as per:
>
> http://www.eclipse.org/aspectj/doc/released/adk15notebook/generics-inAspectJ5.html#inter-type-declarations
>
> So here is a test program that shows that:
> ---
> class Target<T> {
>   public void foo(T t) {}
> }
>
> aspect X {
>   public void Target<Z>.goo(Z t) {}
>
>   public <Y> void Target.hoo(Y t) {}
> }
>
> class ITarget extends Target<Integer> {}
>
> public class Test {
>   public static void main(String []argv) {
>     ITarget t= new ITarget();
>     t.foo(new Integer(5));
>
>     // goo can only take Integers
>     t.goo(new Integer(6));
>     // t.goo("BANG"); // not allowed
>
>
>     // Both OK, hoo is just a generic method
>     t.hoo(new Integer(6));
>     t.hoo("BANG");
>   }
> }
> ---
> Notice goo() cannot be invoked with a String because in ITarget the
> type variable has been bound to Integer.  hoo() can take anything as
> it is just an ordinary generic method.  Also notice that the letters
> for the type variables dont matter - they are matched by position, so
> an ITD on Target with <Z> says 'within this declaration Z matches the
> first type variable declared in Target'.  We don't rely on name
> matching here.
>
> Having said all that, there are open bugs for generic ITDs onto types
> when binary weaving, ie. not all from source like the test program
> above, and I would not be surprised if you are hitting one of those
> when trying to ITD onto TextComponent.  That's why I asked if you were
> binary weaving in my first reply...
>
> cheers,
> Andy.
>
>
>
>
>
> On 13/04/2008, Simone Gianni <simoneg@xxxxxxxxxx> wrote:
>   
>> Hi All,
>>  I solved the thing, but it is a bit strange how to solve it :
>>
>>  public <T> void TextComponent.setConverter(Converter<T> c) {
>>
>>
>>  This is the way it is done in the AspectJ guide to java 5, they always
>>  declare the <T> even if, being used just in one place, it is not needed
>>  in a similar java-only method and <?> or nothing could be used instead.
>>  So, I think this could be a fix in AspectJ, more than just a
>>  clarification in the docs :)
>>
>>  Simone
>>
>>  Simone Gianni wrote:
>>  > Hi Andy,
>>  > Thanks for taking the time for reviewing my code!
>>  >
>>  > A couple of differences :
>>  > - I inferred also the Converter field
>>  > - TextComponent is a binary class i'm weaving without sources
>>  >
>>  > I'm not in office now, but will try it again later and see if i figure
>>  > out by my self where is the difference.
>>  >
>>  > Simone
>>  >
>>  > Andy Clement wrote:
>>  >
>>  >> >From your description it sounds like a bug, but I can't seem to
>>  >> recreate it - this file compiles fine for me:
>>  >>
>>  >> ---
>>  >> class TextComponent {
>>  >>   Converter converter;
>>  >> }
>>  >>
>>  >> interface Converter<T> {
>>  >>   public T fromString(String value);
>>  >>   public String toString(T value);
>>  >> }
>>  >>
>>  >> class IntegerConverter implements Converter<Integer> {
>>  >>   public Integer fromString(String value) { return null; }
>>  >>   public String toString(Integer value) { return null; }
>>  >> }
>>  >>
>>  >> aspect X {
>>  >>   Object Converter.component;
>>  >>
>>  >>   public void TextComponent.setConverter(Converter c) {
>>  >>      this.converter = c;
>>  >>      c.component = this;
>>  >>   }
>>  >> }
>>  >>
>>  >>
>>  >>
>>  >> public class Test {
>>  >>   public static void main(String []argv) {
>>  >>    TextComponent tc = new TextComponent() ;
>>  >>    IntegerConverter ic = new IntegerConverter();
>>  >>    tc.setConverter(ic);
>>  >>   }
>>  >> }
>>  >> ---
>>  >>
>>  >> Can you tell me what I have done differently to you?  Is your
>>  >> TextComponent class generic by any chance?  Is it a binary weave into
>>  >> a library or everything being compiled from source?
>>  >>
>>  >> Andy.
>>  >>
>>  >> On 11/04/2008, Simone Gianni <simoneg@xxxxxxxxxx> wrote:
>>  >>
>>  >>
>>  >>> Hello all,
>>  >>>  I'm moving my first steps in this beautiful world of AOPized Java, but
>>  >>>  in the last 3 hours I've been facing a problem I don't know how to
>>  >>>  solve. Probably it is just a stupid thing, but still ....
>>  >>>
>>  >>>  I have a class, called TextComponent, on which I'm trying to add via
>>  >>>  AspectJ a field and a couple of methods. One of the methods is declared
>>  >>>  this way in my aspect :
>>  >>>
>>  >>>     public void TextComponent.setConverter(Converter c) {
>>  >>>         this.converter = c;
>>  >>>         c.component = this;
>>  >>>     }
>>  >>>
>>  >>>  Now, Converter is a generic interface :
>>  >>>
>>  >>>  public interface Converter<T> {
>>  >>>
>>  >>>     public T fromString(String value);
>>  >>>
>>  >>>     public String toString(T value);
>>  >>>
>>  >>>  }
>>  >>>
>>  >>>
>>  >>>  Which then has an implementation :
>>  >>>
>>  >>>  public class IntegerConverter implements Converter<Integer> {
>>  >>>  ....
>>  >>>  }
>>  >>>
>>  >>>
>>  >>>  Now, I weave the project containing TextComponent, i get the method
>>  >>>  added, but then when i try to do :
>>  >>>
>>  >>>  TextComponent tc = new TextComponent();
>>  >>>  IntegerConverter ic = new IntegerConverter();
>>  >>>  tc.setConverter(ic);
>>  >>>
>>  >>>  I get an error, both from AJDT inside Eclipse and from ajc invoked in
>>  >>>  the Maven build. The error is :
>>  >>>
>>  >>>  The method setConverter(Converter<T>) in the type TextComponent is not
>>  >>>  applicable for the arguments (IntegerConverter)
>>  >>>
>>  >>>  Mh, I tried this on a plain class, instead than on an inferred method,
>>  >>>  just to make sure I was not missing something in the generics field. I
>>  >>>  also tried to declare the method differently (like
>>  >>>  setConverter(Converter<?> c) etc..) .. but still it does not work.
>>  >>>
>>  >>>  Declaring it as setConverter(Object c) and then casting c to a Converter
>>  >>>  (or Converter<?>) works perfectly.
>>  >>>
>>  >>>  I'm using version 1.5.4 or AspectJ.
>>  >>>
>>  >>>
>>  >>>  Any idea?
>>  >>>
>>  >>>  Simone
>>  >>>  _______________________________________________
>>  >>>  aspectj-users mailing list
>>  >>>  aspectj-users@xxxxxxxxxxx
>>  >>>  https://dev.eclipse.org/mailman/listinfo/aspectj-users
>>  >>>
>>  >>>
>>  >>>
>>  >> _______________________________________________
>>  >> aspectj-users mailing list
>>  >> aspectj-users@xxxxxxxxxxx
>>  >> https://dev.eclipse.org/mailman/listinfo/aspectj-users
>>  >>
>>  >>
>>  >
>>  > _______________________________________________
>>  > aspectj-users mailing list
>>  > aspectj-users@xxxxxxxxxxx
>>  > https://dev.eclipse.org/mailman/listinfo/aspectj-users
>>  >
>>
>>  _______________________________________________
>>  aspectj-users mailing list
>>  aspectj-users@xxxxxxxxxxx
>>  https://dev.eclipse.org/mailman/listinfo/aspectj-users
>>
>>     
> _______________________________________________
> aspectj-users mailing list
> aspectj-users@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/aspectj-users
>   



Back to the top