Status: New
Owner: ----
Labels: Type-Patch Component-Core

New issue 743 by [email protected]: Move constructionContext.removeCurrentReference from ConstructorInjector.construct to ConstructorInjector.provision?
http://code.google.com/p/google-guice/issues/detail?id=743

See https://groups.google.com/d/topic/google-guice/OeEEg2ELQ0M/discussion

TestCase from https://gist.github.com/electrotype/5108107:

//-------------------------------------------------------------------
import static org.junit.Assert.*;

import java.util.UUID;

import org.junit.Test;

import com.google.inject.AbstractModule;
import com.google.inject.Binding;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.FactoryModuleBuilder;
import com.google.inject.matcher.AbstractMatcher;
import com.google.inject.spi.ProvisionListener;

public class ExampleTest
{
    public static class ClassAAA
    {
        private final String id;
        private final boolean myParam;
        private final IClassBBBFactory classBBBFactory;
        private ClassBBB clasBBB;

        @Inject
        public ClassAAA(@Assisted boolean myParam,
                        IClassBBBFactory classBBBFactory)
        {
            this.myParam = myParam;
            this.id = UUID.randomUUID().toString();
            this.classBBBFactory = classBBBFactory;
        }

        public void init()
        {
            if(this.myParam)
            {
this.clasBBB = this.classBBBFactory.create(UUID.randomUUID().toString());
            }
        }

        public String getId()
        {
            return this.id;
        }

        public ClassBBB getClassBBB()
        {
            return this.clasBBB;
        }
    }

    public static class ClassBBB
    {
        private final IClassAAAFactory classAAAFactory;
        private ClassAAA clasAAACreatedByClassBBB;

        @Inject
        public ClassBBB(@Assisted String myParam,
                        IClassAAAFactory classAAAFactory)
        {
            this.classAAAFactory = classAAAFactory;
        }

        public void init()
        {
// The problem is here. Even if the factory should return a new instance
            // of ClassAAA, it returns the one that is creating ClassBBB!
this.clasAAACreatedByClassBBB = this.classAAAFactory.create(false);
        }

        public ClassAAA getClasAAACreatedByClassBBB()
        {
            return this.clasAAACreatedByClassBBB;
        }
    }

    public static interface IClassAAAFactory
    {
        public ClassAAA create(boolean someParam);
    }

    public static interface IClassBBBFactory
    {
        public ClassBBB create(String someParam);
    }

    @Test
    public void bugGuiceConstructorInjector()
    {
        Injector injector = Guice.createInjector(new AbstractModule()
        {
            @Override
            protected void configure()
            {
                bindListener(new AbstractMatcher<Binding<?>>()
                             {
                                @Override
                                public boolean matches(Binding<?> t)
                                {
return ClassAAA.class.isAssignableFrom(t.getKey().getTypeLiteral().getRawType()) || ClassBBB.class.isAssignableFrom(t.getKey().getTypeLiteral().getRawType());
                                }
                             },

                             new ProvisionListener()
                            {
                                @Override
public <T> void onProvision(ProvisionInvocation<T> provision)
                                {
                                    Object obj = provision.provision();
                                    if(obj instanceof ClassAAA)
                                    {
                                        ((ClassAAA)obj).init();
                                    }
                                    if(obj instanceof ClassBBB)
                                    {
                                        ((ClassBBB)obj).init();
                                    }
                                }
                            });

install(new FactoryModuleBuilder().build(IClassAAAFactory.class)); install(new FactoryModuleBuilder().build(IClassBBBFactory.class));
            }
        });

IClassAAAFactory classAAAFactory = injector.getInstance(IClassAAAFactory.class);
        ClassAAA classAAA = classAAAFactory.create(true);

        // Shouldn't be the same id!
assertNotEquals(classAAA.getClassBBB().getClasAAACreatedByClassBBB().getId(), classAAA.getId());

    }
}
//-------------------------------------------------------------------

Proposed patch:

//-------------------------------------------------------------------
diff --git a/core/src/com/google/inject/internal/ConstructorInjector.java b/core/src/com/google/inject/internal/Construc
index e71a25a..8f86db5 100644
--- a/core/src/com/google/inject/internal/ConstructorInjector.java
+++ b/core/src/com/google/inject/internal/ConstructorInjector.java
@@ -94,7 +94,6 @@ final class ConstructorInjector<T> {
         });
       }
     } finally {
-      constructionContext.removeCurrentReference();
       constructionContext.finishConstruction();
     }
   }
@@ -125,6 +124,8 @@ final class ConstructorInjector<T> {
           : userException;
       throw errors.withSource(constructionProxy.getInjectionPoint())
           .errorInjectingConstructor(cause).toException();
+    } finally {
+      constructionContext.removeCurrentReference();
     }
   }
 }
//-------------------------------------------------------------------


--
You received this message because this project is configured to send all issue notifications to this address.
You may adjust your notification preferences at:
https://code.google.com/hosting/settings

--
You received this message because you are subscribed to the Google Groups 
"google-guice-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/google-guice-dev?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to