Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AspectJ compiler bug leads to StackOverflowError

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!

like image 995
Emanuele Fusco Avatar asked Oct 31 '17 07:10

Emanuele Fusco


People also ask

What causes Java Lang StackOverflowError?

StackOverflowError is a runtime error which points to serious problems that cannot be caught by an application. The java. lang. StackOverflowError indicates that the application stack is exhausted and is usually caused by deep or infinite recursion.

Can we handle StackOverflowError?

To handle StackoverFlowError, you should carefully inspect the stack trace to detect any repeating call patterns in your code. These indicate recursive calls to your code or function. Some traits of recursion: Large thread stacks that appear to repeat.

Why am I getting a stack overflow error?

A stack overflow is a type of buffer overflow error that occurs when a computer program tries to use more memory space in the call stack than has been allocated to that stack.


1 Answers

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

like image 186
Emanuele Fusco Avatar answered Sep 21 '22 02:09

Emanuele Fusco