Search code examples
javaclassjavafxreflections

`Class<? extends BaseTab>.newInstance()` throws java.lang.StackOverflowError with Reflections


Code:

Reflections reflections = new Reflections("com.erby.tab.tabs");

for(Class<? extends BaseTab> t : reflections.getSubTypesOf(BaseTab.class)) {
    try {
        BaseTab tab = t.newInstance();

        System.out.println(tab.toString());
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

BaseTab.java:

public abstract class BaseTab extends Tab implements Serializable {
    public abstract String getPrefix();

    @Override
    public abstract String toString();
}

HomeTab.java:

public class HomeTab extends BaseTab {
    public HomeTab() {
        setText(toString());
    }

    @Override
    public String getPrefix() {
        return "home";
    }

    @Override
    public String toString() {
        return "Home Tab";
    }
}

When calling this I get:

Caused by: java.lang.StackOverflowError
at sun.misc.URLClassPath.getLoader(URLClassPath.java:476)
at sun.misc.URLClassPath.getNextLoader(URLClassPath.java:457)
at sun.misc.URLClassPath.access$100(URLClassPath.java:64)
at sun.misc.URLClassPath$1.next(URLClassPath.java:239)
at sun.misc.URLClassPath$1.hasMoreElements(URLClassPath.java:250)
at java.net.URLClassLoader$3$1.run(URLClassLoader.java:601)
at java.net.URLClassLoader$3$1.run(URLClassLoader.java:599)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader$3.next(URLClassLoader.java:598)
at java.net.URLClassLoader$3.hasMoreElements(URLClassLoader.java:623)
at sun.misc.CompoundEnumeration.next(CompoundEnumeration.java:45)
at sun.misc.CompoundEnumeration.hasMoreElements(CompoundEnumeration.java:54)
at sun.misc.CompoundEnumeration.next(CompoundEnumeration.java:45)
at sun.misc.CompoundEnumeration.hasMoreElements(CompoundEnumeration.java:54)
at org.reflections.util.ClasspathHelper.forResource(ClasspathHelper.java:61)
at org.reflections.util.ClasspathHelper.forPackage(ClasspathHelper.java:51)
at org.reflections.util.ConfigurationBuilder.build(ConfigurationBuilder.java:93)
at org.reflections.Reflections.<init>(Reflections.java:170)
at org.reflections.Reflections.<init>(Reflections.java:143)
at com.erby.tab.tabs.TestTab.<init>(TestTab.java:20)
at sun.reflect.GeneratedConstructorAccessor2.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
at java.lang.Class.newInstance(Class.java:442)
at com.erby.tab.tabs.TestTab.<init>(TestTab.java:24)
at sun.reflect.GeneratedConstructorAccessor2.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
at java.lang.Class.newInstance(Class.java:442)
at com.erby.tab.tabs.TestTab.<init>(TestTab.java:24)
at sun.reflect.GeneratedConstructorAccessor2.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
at java.lang.Class.newInstance(Class.java:442)

FYI BaseTab is extending off the javafx Tab.

I found out that it was iterating over every class and creating hundreds of instances before it gets the error. The questing is where is my code going wrong and how can I fix it? Thanks.


Solution

  • As you wrote in your comment, the first code snippet appears in a constructor. That snippet creates new instances, which causes that consturctor to be called again. This results in an infinite recursion that ends in stack overflow error.