bineanzhou / google-guice

Automatically exported from code.google.com/p/google-guice
Apache License 2.0
0 stars 0 forks source link

Provider methods circular dependency StackOverflowError #177

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Using a modified version of the current unit test.
{{{
package chapter8.providermethods;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import com.google.inject.Binder;
import com.google.inject.BindingAnnotation;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Module;
import com.google.inject.ProviderMethods;
import com.google.inject.Provides;
import com.google.inject.Singleton;

public class Main {
    public static void main(String[] args) {
        Injector injector = Guice.createInjector(new Module() {
            public void configure(Binder binder) {
                binder.install(ProviderMethods.from(new Main()));
            }
        });

        Bob bob = injector.getInstance(Key.get(Bob.class, Sole.class));
    }
    @Provides
    Bob provideBob(final Dagny dagny) {
        return new Bob() {
            public String getName() {
                return "A Bob";
            }

            public Dagny getDaughter() {
                return dagny;
            }
        };
    }

    @Provides
    @Singleton
    @Sole
    Bob provideSoleBob(final Dagny dagny) {
        return new Bob() {
            public String getName() {
                return "Only Bob";
            }

            public Dagny getDaughter() {
                return dagny;
            }
        };
    }

    @Provides
    @Singleton
    Dagny provideDagny(final @Sole Bob bob) {
        return new Dagny() {
            public int getAge() {
                return 1;
            }
            public Bob getDad() {
                return bob;
            }
        };
    }
    interface Bob {
        String getName();

        Dagny getDaughter();
    }

    interface Dagny {
        int getAge();
        Bob getDad();
    }

    @Retention(RetentionPolicy.RUNTIME)
    @Target( { ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
    @BindingAnnotation
    @interface Sole {
    }

}
}}}

Original issue reported on code.google.com by robbie.v...@gmail.com on 2 Feb 2008 at 6:37

GoogleCodeExporter commented 9 years ago
This is kind of like a halting problem, since it's difficult to say (when 
scopes etc. are involved) whether this is 
actually a legal setup. I'm sure we could try to detect this, but we certainly 
won't be able to detect all cases. 
Consider a variant:

    @Provides
    Bob provideBob(final Provider<Dagny> dagnyProvider) {
        Dagne dagne = new Random().nextInt() == 5 ? dagneProvider.get() : new CrazyDagne();
        ...
    }

In this case, the program should eventually halt, but it's very difficult to 
detect that just by looking at the 
method signatures and examining behaviour.

I'm going to mark this as 'WontFix', just because solving the general case is 
impossible and solving the 
specific case is quite complex. There's a lot of ways to write infinite loops 
and stack overflows, and it's not a 
winning business to try and detect and prevent them all.

Original comment by limpbizkit on 29 May 2008 at 3:52