frjaeger220 / google-guice

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

Strange behavior on Inject Injector instance in Constructor #353

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
I can't explain why and can't create little example with error. I try to 
attach my project but system reject my submit. I can give all required 
information. Can send my sources

Run ru.faulab.fmsgenerator.FMSRunTest.

Look on class ru.faulab.fmsgenerator.gui.GUI. It has unnecessary dependency  
on FMSDocuments constructor

@Inject
public GUI(Injector parentInjector, FMSDocuments fmsDocuments)

BUT WHEN I REMOVE THIS DEPENDENCY like 

@Inject
public GUI(Injector parentInjector)

I got the error

Exception in thread "main" com.google.inject.ProvisionException: Guice 
provision errors:

1) No implementation for 
java.util.Set<ru.faulab.fmsgenerator.core.document.DocumentTemplate> was 
bound.
  while locating 
java.util.Set<ru.faulab.fmsgenerator.core.document.DocumentTemplate>
    for parameter 0 at 
ru.faulab.fmsgenerator.core.document.DocumentTemplateHolder.<init>(Document
TemplateHolder.java:20)
  while locating 
ru.faulab.fmsgenerator.core.document.DocumentTemplateHolder
    for parameter 1 at 
ru.faulab.fmsgenerator.gui.action.GenerateAction.<init>(GenerateAction.java
:30)
  at ru.faulab.fmsgenerator.gui.GUIModule.configure(GUIModule.java:29)
  at ru.faulab.fmsgenerator.gui.GUI.<init>(GUI.java:25)
  while locating ru.faulab.fmsgenerator.gui.GUI
  while locating ru.faulab.fmsgenerator.core.XUI

WHY???. Please Explain me. This is a bug or feature.

Original issue reported on code.google.com by tregu...@gmail.com on 5 Apr 2009 at 3:47

GoogleCodeExporter commented 9 years ago
P.S I Used 

* guice-assistedinject-snapshot20090205.jar
* guice-multibindings-snapshot20090205.jar
* guice-snapshot20090205.jar
* fop-0.95
* poi-3.2
* substance

Original comment by tregu...@gmail.com on 5 Apr 2009 at 3:51

GoogleCodeExporter commented 9 years ago
Some Investigations:

I have Root Injector(#1). One Child injector(#2) under it. And One Child 
Injector(#3) 
under it (it's create in Constructor ru.faulab.fmsgenerator.gui.GUI). 
FMSDocuments 
register in middle child injector(#2) like 
this.bind(FMSDocuments.class).in(Singleton.class);

java.util.Set<ru.faulab.fmsgenerator.core.document.DocumentTemplate> - register 
in 
this injector too like this.install(new DocumentModule());

When GUI has dependecy to FMSDocument it got Injector refernced to #2 but when 
i 
remove this dependnecy in constructir i got Injector refernced to #1. 

I think this information can help you

Original comment by tregu...@gmail.com on 5 Apr 2009 at 4:01

GoogleCodeExporter commented 9 years ago
I create little Example with BAG. You can see it in attachment.

You can reproduce the Bag here 
static class ChildService1Impl implements ChildService1
    {
        @Inject                                   
        public ChildService1Impl(Injector injector)  /*BAG*/
//        public ChildService1Impl(Injector injector,ChildService2Impl 
childService2) 
/*ALL WORK*/
        {
            System.out.println(injector.getParent());
        }
    }

When You in /*BAG*/ version you got null in System.out. Mean Root Injector
But when you run /*ALL WORK*/ version you got 

Injector[bindings=[ProviderInstanceBinding[key=Key[type=com.google.inject.Inject
or, 
annotation=[none]], source=[unknown source], scope=Scopes.NO_SCOPE, 
provider=Provider<Injector>], 
ProviderInstanceBinding[key=Key[type=java.util.logging.Logger, 
annotation=[none]], 
source=[unknown source], scope=Scopes.NO_SCOPE, provider=Provider<Logger>], 
InstanceBinding[key=Key[type=com.google.inject.Stage, annotation=[none]], 
source=[unknown source], instance=DEVELOPMENT], 
ProviderInstanceBinding[key=Key[type=ru.faulab.fmsgenerator.GuiceBagExample$IRoo
tServ
iceFactory, annotation=[none]], 
source=ru.faulab.fmsgenerator.GuiceBagExample$RootSubModule1.configure(GuiceBagE
xampl
e.java:52), scope=Scopes.SINGLETON, 
provider=ru.faulab.fmsgenerator.GuiceBagExample$IRootServiceFactory for 
ru.faulab.fmsgenerator.GuiceBagExample$IRootServiceImpl], 
LinkedKeyBinding[key=Key[type=ru.faulab.fmsgenerator.GuiceBagExample$IRootServic
e2, 
annotation=[none]], 
source=ru.faulab.fmsgenerator.GuiceBagExample$RootSubModule2.configure(GuiceBagE
xampl
e.java:60), scope=Scopes.SINGLETON, 
target=Key[type=ru.faulab.fmsgenerator.GuiceBagExample$IRootService2Impl, 
annotation=[none]]]]] in System Out. Mean Child Injector

Original comment by tregu...@gmail.com on 11 Apr 2009 at 10:15

Attachments:

GoogleCodeExporter commented 9 years ago
If you read the doc carefully for createChildInjector(), it suggests that the 
binding for GUI will live in the top-
level injector: 
   "Just-in-time bindings created for child injectors will be created in an ancestor injector whenever possible. 
This allows for scoped instances to be shared between injectors. Use explicit 
bindings to prevent bindings 
from being shared with the parent injector."

The solution is to use an explicit binding for GUI. In your child injector, add 
this statement:
  bind(GUI.class);

http://google-guice.googlecode.com/svn/trunk/latest-
javadoc/com/google/inject/Injector.html#createChildInjector(com.google.inject.Mo
dule...)

Original comment by limpbizkit on 11 Apr 2009 at 5:15

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
thank you very much. I miss this section, but it not so obvious (IMHO). But i 
don't 
understand your solustion. If i wrote as you say bind(GUI.class);, i lost 
ability to 
get instance by interface like injector.getInstance(XUI.class). (GUI extends 
JFrame 
implements XUI).

So i have only one way, as i understand, use unnecessary dependency. :(

Original comment by tregu...@gmail.com on 11 Apr 2009 at 5:53