eclipse-jdt / eclipse.jdt.core

Eclipse Public License 2.0
162 stars 131 forks source link

StackOverflowError in TypeBinding.getQualifiedName(TypeBinding.java:748) #1838

Closed guw closed 9 months ago

guw commented 9 months ago

I got an interesting stacktrace today. This happens within a wildcard/intersection type. I wonder if this code needs some protection. I do suspect this is because of dealing with some generic speciality constructs in the code being analyzed.

java.lang.StackOverflowError
    at java.base/java.util.concurrent.ConcurrentHashMap.comparableClassFor(ConcurrentHashMap.java:714)
    at java.base/java.util.concurrent.ConcurrentHashMap$TreeNode.findTreeNode(ConcurrentHashMap.java:2750)
    at java.base/java.util.concurrent.ConcurrentHashMap$TreeNode.findTreeNode(ConcurrentHashMap.java:2753)
    at java.base/java.util.concurrent.ConcurrentHashMap$TreeNode.findTreeNode(ConcurrentHashMap.java:2753)
    at java.base/java.util.concurrent.ConcurrentHashMap$TreeNode.findTreeNode(ConcurrentHashMap.java:2753)
    at java.base/java.util.concurrent.ConcurrentHashMap$TreeNode.findTreeNode(ConcurrentHashMap.java:2753)
    at java.base/java.util.concurrent.ConcurrentHashMap$TreeNode.findTreeNode(ConcurrentHashMap.java:2753)
    at java.base/java.util.concurrent.ConcurrentHashMap$TreeNode.findTreeNode(ConcurrentHashMap.java:2753)
    at java.base/java.util.concurrent.ConcurrentHashMap$TreeNode.findTreeNode(ConcurrentHashMap.java:2753)
    at java.base/java.util.concurrent.ConcurrentHashMap$TreeNode.findTreeNode(ConcurrentHashMap.java:2753)
    at java.base/java.util.concurrent.ConcurrentHashMap$TreeNode.findTreeNode(ConcurrentHashMap.java:2753)
    at java.base/java.util.concurrent.ConcurrentHashMap$TreeBin.find(ConcurrentHashMap.java:2903)
    at java.base/java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:944)
    at org.eclipse.jdt.core.dom.DefaultBindingResolver.internalGetTypeBinding(DefaultBindingResolver.java:424)
    at org.eclipse.jdt.core.dom.DefaultBindingResolver.getTypeBinding(DefaultBindingResolver.java:380)
    at org.eclipse.jdt.core.dom.TypeBinding.getBound(TypeBinding.java:197)
    at org.eclipse.jdt.core.dom.TypeBinding.getQualifiedName(TypeBinding.java:739)
    at org.eclipse.jdt.core.dom.TypeBinding.getQualifiedName(TypeBinding.java:748)
    at org.eclipse.jdt.core.dom.TypeBinding.getQualifiedName(TypeBinding.java:748)
    at org.eclipse.jdt.core.dom.TypeBinding.getQualifiedName(TypeBinding.java:748)
    at org.eclipse.jdt.core.dom.TypeBinding.getQualifiedName(TypeBinding.java:748)
    at org.eclipse.jdt.core.dom.TypeBinding.getQualifiedName(TypeBinding.java:748)
    at org.eclipse.jdt.core.dom.TypeBinding.getQualifiedName(TypeBinding.java:748)
    at org.eclipse.jdt.core.dom.TypeBinding.getQualifiedName(TypeBinding.java:748)
    at org.eclipse.jdt.core.dom.TypeBinding.getQualifiedName(TypeBinding.java:748)
    at org.eclipse.jdt.core.dom.TypeBinding.getQualifiedName(TypeBinding.java:748)
    at org.eclipse.jdt.core.dom.TypeBinding.getQualifiedName(TypeBinding.java:748)
    at org.eclipse.jdt.core.dom.TypeBinding.getQualifiedName(TypeBinding.java:748)
    at org.eclipse.jdt.core.dom.TypeBinding.getQualifiedName(TypeBinding.java:748)
    at org.eclipse.jdt.core.dom.TypeBinding.getQualifiedName(TypeBinding.java:748)
    at org.eclipse.jdt.core.dom.TypeBinding.getQualifiedName(TypeBinding.java:748)
    at org.eclipse.jdt.core.dom.TypeBinding.getQualifiedName(TypeBinding.java:748)
    at org.eclipse.jdt.core.dom.TypeBinding.getQualifiedName(TypeBinding.java:748)
    at org.eclipse.jdt.core.dom.TypeBinding.getQualifiedName(TypeBinding.java:748)
    at org.eclipse.jdt.core.dom.TypeBinding.getQualifiedName(TypeBinding.java:748)
    at org.eclipse.jdt.core.dom.TypeBinding.getQualifiedName(TypeBinding.java:748)
    at org.eclipse.jdt.core.dom.TypeBinding.getQualifiedName(TypeBinding.java:748)
    at org.eclipse.jdt.core.dom.TypeBinding.getQualifiedName(TypeBinding.java:748)
    at org.eclipse.jdt.core.dom.TypeBinding.getQualifiedName(TypeBinding.java:748)
    at org.eclipse.jdt.core.dom.TypeBinding.getQualifiedName(TypeBinding.java:748)
    at org.eclipse.jdt.core.dom.TypeBinding.getQualifiedName(TypeBinding.java:748)
    at org.eclipse.jdt.core.dom.TypeBinding.getQualifiedName(TypeBinding.java:748)
    at org.eclipse.jdt.core.dom.TypeBinding.getQualifiedName(TypeBinding.java:748)
    at org.eclipse.jdt.core.dom.TypeBinding.getQualifiedName(TypeBinding.java:748)
    at org.eclipse.jdt.core.dom.TypeBinding.getQualifiedName(TypeBinding.java:748)
    at org.eclipse.jdt.core.dom.TypeBinding.getQualifiedName(TypeBinding.java:748)
    at (1000 more lines with same location)

Here is what I am doing:

IProject project = ...;
IType typeToImport = ...;

// collect all jars needed on the classpath for resolving IType
Set<IPath> jars = new HashSet<>();

// recursion protection
Set<String> processedTypes = new HashSet<>();

ASTParser parser = ASTParser.newParser(AST.getJLSLatest());
parser.setProject(JavaCore.create(project));

parser.setIgnoreMethodBodies(true);
parser.setResolveBindings(true);

IBinding[] bindings = parser.createBindings(new IJavaElement[] { typeToImport }, monitor.split(1));
for (final IBinding binding : bindings) {
    collectDependenciesFromType((ITypeBinding) binding, jars, processedTypes, monitor.split(1));
}

Another possibility could be class files on the classpath processed by AspectJ.

Version: 2023-12 (4.30.0) Build id: 20231201-2043

iloveeclipse commented 9 months ago
guw commented 9 months ago

No other information in the log. This is programmatically using ASTParser. It's very likely something on the classpath. Still debugging.

guw commented 9 months ago

Ok, so this is interesting. When traversing an ITypeBinding to discover all possible dependencies parameterized types can cause a recursion.

Example:

public class ExpandableArray<E> implements Serializable, Iterable<E>, Comparable<ExpandableArray> {
    public ExpandableArray(ExpandableArray<? extends E> m) {
        ...
    }
}

Here is what's happening:

-> type:   ExpandableArray<common.udd.constants.CustomEntityOptionsBit>
-> method: public void <init>(ExpandableArray<? extends common.udd.constants.CustomEntityOptionsBit>) 
           -> methodBinding.getParameterTypes:
-> type:   ExpandableArray<? extends common.udd.constants.CustomEntityOptionsBit>
...
-> type:   ExpandableArray<? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ? extends ...

So turns out this was an unhandled piece in the recursion collection code.

if(binding.isParameterizedType()) {
    // for parameterized types we look at the erasure and the type arguments only (https://github.com/eclipse-jdt/eclipse.jdt.core/issues/1838)
    collectDependenciesFromType(binding.getTypeDeclaration(), dependencies, processedTypes, monitor);
    for (final ITypeBinding typeArgument : binding.getTypeArguments()) {
        collectDependenciesFromType(typeArgument, dependencies, processedTypes, monitor);
    }
    return; // done
}