9

I run into a StackOverflow error of the AspectJ compiler today and I thought I should share it on StackOverflow :-) To reproduce the error I made a toy example

public abstract class Node<T,Q extends Node<T,Q>> implements WithParent<Q>{
    private T content;
    //getter and setter for content
}
public aspect WithParentAspect {
    private T WithParent<T>.parent;
    public T WithParent<T>.getParent() {
        return this.parent;
    }
    public void WithParent<T>.setParent(T parent) {
        this.parent=parent;
    }
}
public interface WithParent<T> { }
public class StringContentNode extends Node<String, StringContentNode>{
    public static void main (String [] args) {
        StringContentNode root = new StringContentNode();
        StringContentNode leaf = new StringContentNode();

        root.setContent("root");
        leaf.setContent("leaf");
        leaf.setParent(root);
        System.out.println(leaf);                   
        System.out.println(leaf.getParent());
    }
}

Trying to compile this code results in the following error:

java.lang.StackOverflowError
at org.aspectj.weaver.World$TypeMap.put(World.java:1198)
at org.aspectj.weaver.World.resolve(World.java:398)
at org.aspectj.weaver.World.resolve(World.java:277)
at org.aspectj.weaver.World.resolve(World.java:229)
at org.aspectj.weaver.UnresolvedType.resolve(UnresolvedType.java:615)
at org.aspectj.weaver.ReferenceType.isAssignableFrom(ReferenceType.java:621)
at org.aspectj.weaver.ReferenceType.isAssignableFrom(Ref ...
bleFrom(ReferenceType.java:459)
at org.aspectj.weaver.TypeVariable.isASubtypeOf(TypeVariable.java:201)  

However, if I modify the Generics in the Node class to

public abstract class Node<T,Q extends Node<T,?>> implements WithParent<Q>{
...

(notice the ? instead of Q), the program works, and prints what you would expect:

Node (content=leaf, parent=Node (content=root, parent=null))
Node (content=root, parent=null)

even though Eclipse complains that

The method setParent(StringContentNode) is undefined for the type StringContentNode

if I leave the WithParent Interface empty as is now, or that

The type StringContentNode must implement the inherited abstract method WithParent.getParent()

If I define the getter and the setter in the interface.
Should I signal the bug? Is there a cleaner way to achieve the same functionality, without incurring in any weird compilation issue? Thanks!

Emanuele Fusco
  • 809
  • 6
  • 11
  • 2
    From my point of view, when a compiler throws an exception, I consider it a bug, no matter how complicated construct are you trying to use. So I think it's definitely worth reporting it. – Nándor Előd Fekete Nov 01 '17 at 01:35
  • 2
    I reported the bug, https://bugs.eclipse.org/bugs/show_bug.cgi?id=526707 Can I ask you whether you were able to replicate the bug? Thanks... – Emanuele Fusco Nov 01 '17 at 10:33
  • I do not quite get the reason for the down vote... I believe a bug in a mainstream compiler should be of interest to the community, maybe I am wrong. – Emanuele Fusco Nov 19 '17 at 11:08
  • 2
    @EmanueleFusco I believe it's due to this "question" not actually being a question. Countless numbers of bugs are being reported every single day, yet no one really creates a QUESTION on stackoverflow for every single one of them. – Cargeh Nov 20 '17 at 10:45
  • @Cargeh fair enough... I guess I'll have to wait for the bug report to be handled. – Emanuele Fusco Nov 20 '17 at 13:14
  • @EmanueleFusco moveover, what are you offering the bounty for? (most people have come here for that). What do I gotta do to get that +50 rep? Or is it just clickbait? In which case the answer to "why am I getting downvoted" is obvious – Cargeh Nov 20 '17 at 13:40
  • 2
    @Caregh well, for example tell me that you can replicate the bug, so that I'm sure the bug report I filed, when handled, will actually show that there is a bug. I am also curious to know if other people uses AspectJ differently by the way I did to implement delegates, as I asked in the question and in the bounty... Anyhow I'm sorry if I have offended someone. Cheers... – Emanuele Fusco Nov 20 '17 at 23:37
  • 1
    SO is a Q/A platform, not a forum. You have not asked a real question, it is unclear what a "correct answer" to your "question" could be, and finally you even admit that you ran into the problem the same day you posted the "question", i.e. you do not want to wait until someone reacts to your bug ticket. Making the problem reproduceable for the AspectJ ticket is your own job, not the SO community's. I suggest you delete your post, but of course it is your decision. – kriegaex Nov 23 '17 at 11:56
  • Besides, even though I have not tested it (no PC available at the moment) and am not a generics expert, I think that `Q extends Node` somehow looks illogical. How can Q extend something containing itself? It sems like this construct is crying for an endless loop and thus for a stack overflow. It might not be an AspectJ problem at all but a Java one. – kriegaex Nov 23 '17 at 12:00
  • 2
    @kriegaex that's a perfectly reasonable use case, we actually have a name for it, it's called _recursive_ or _self-referencing_ or _self-bound_ generics, and a prominent example of it is the declaration of the `Enum` class in the JDK: `abstract class Enum> ...` – Nándor Előd Fekete Nov 23 '17 at 18:02
  • @Nándor Előd Fekete thanks. – Emanuele Fusco Nov 23 '17 at 20:25
  • 1
    @EmanueleFusco In spite of your types (or any type declaration for that matter) being completely legitimate, I think the guys here have a point in that your question is not really a question in the stackoverflow sense of the word. Thank you for finding and reporting the bug on Eclipse Bugzilla, but I don't really see this could be answered in any meaningful way, except by acknowledging and fixing the bug by the AspectJ maintainers. I hope they fix it ASAP as I see this as a serious bug in the AspectJ compiler and I cast my vote accordingly on bugzilla. I encourage others here to do the same. – Nándor Előd Fekete Nov 23 '17 at 20:38
  • Thanks Nándor for pointing me to recursive generics. It is always nice to learn something new here. :-) As I said, I am no generics expert and nowhere near a PC in order to try for myself. The recursive declaration just seemed odd when reading it in the very context of a stack overflow error which is often caused by recursion. Maybe this is even the problem in the AspectJ compiler, but again I am just speculating. – kriegaex Nov 23 '17 at 22:54
  • @kriegaex If it were some syntactic or semantic error that would not be supported by javac either, then it should report an error message similarly how javac would behave (in theory). But this is not the case, it's not reporting a compile error, it's crashing with a `StackOverflowError`. So it's a clear bug IMO. – Nándor Előd Fekete Nov 24 '17 at 01:09
  • Of course, I never doubted that. Thus my first comment. No need to convince me. The other comment about generics was just a BTW and I was wrong because I was without access to PC and compiler, could not try and maybe should not have made an educated guess in the first place. But even then I said that I am no generics expert and after your correction I thanked you. So can we stop here, please? My main concern still is that this question has not been deleted by its author yet. – kriegaex Nov 24 '17 at 05:53
  • 1
    @kriegaex this question is back linked in my bug report, moreover I still think it may be interesting to some. You don't have to provide an answer, please just ignore my question since you find it uninteresting. – Emanuele Fusco Nov 24 '17 at 07:40
  • 1
    The point is that there is no question and no valid answer is possible. Ergo SO is the wrong platform. This is not a blackboard for interesting topics but for concrete, answerable questions which get closed by the author accepting the right answer. – kriegaex Nov 24 '17 at 13:33
  • @kriegaex sorry man, I may have misunderstood you. I didn't mean to come over as a smartass :) All the best! – Nándor Előd Fekete Nov 24 '17 at 15:43
  • I don't understand all this fuss. What is wrong with you guys? The OP is asking for a workaround or a cleaner way. "Should I signal the bug? Is there a cleaner way to achieve the same functionality, without incurring in any weird compilation issue?" – Pablo Feb 23 '18 at 19:55

1 Answers1

2

It seems no one will propose a workaround that allows to keep implementing recursive generics interfaces through AspectJ in spite of the bug. It would have been interesting to find such a solution but I guess it is not likely to exist.

Please cast your votes on the bug report https://bugs.eclipse.org/bugs/show_bug.cgi?id=526707 if you can.

Cheers.


update: according to Tim Wright the bug is fixed in version 1.9.5 of aspectjrt

Emanuele Fusco
  • 809
  • 6
  • 11