TNG / ArchUnit

A Java architecture test library, to specify and assert architecture rules in plain Java
http://archunit.org
Apache License 2.0
3.17k stars 287 forks source link

JavaType#getAllInvolvedRawTypes() throws StackOverflowError with self-referential generic types #1237

Closed rashtao closed 4 months ago

rashtao commented 7 months ago

JavaType#getAllInvolvedRawTypes() throws StackOverflowError when invoked on a self-referential generic type.

The problem can be reproduced with the following code snippet:

import com.tngtech.archunit.base.DescribedPredicate;
import com.tngtech.archunit.core.domain.JavaMethod;
import com.tngtech.archunit.core.importer.ClassFileImporter;

import static com.tngtech.archunit.lang.conditions.ArchConditions.be;
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.methods;

public abstract class Foo<T extends Foo<T>> {
    public abstract T getThis();

    public static void main(String[] args) {
        methods()
                .should(be(new DescribedPredicate<JavaMethod>("allInvolvedRawTypes") {
                    @Override
                    public boolean test(JavaMethod m) {
                        return m.getReturnType().getAllInvolvedRawTypes().stream().allMatch(alwaysTrue());
                    }
                }))
                .check(new ClassFileImporter().importClasses(Foo.class));
    }
}
codecholeric commented 5 months ago

Thanks for reporting! You're right that this is a bug 🙈 I'm gonna try to fix it as soon as I can find some free time to focus (spontaneously I'm not sure without introducing unwanted public API...)

codecholeric commented 5 months ago

(if anybody else has more time available feel free to grab this)