    001    /*****************************************************************************
    002     * Copyright (C) PicoContainer Organization. All rights reserved.            *
    003     * ------------------------------------------------------------------------- *
    004     * The software in this package is published under the terms of the BSD      *
    005     * style license a copy of which has been included with this distribution in *
    006     * the LICENSE.txt file.                                                     *
    007     *                                                                           *
    008     * Original code by                                                          *
    009     *****************************************************************************/
    010    package org.picocontainer.alternatives.issues;
    011
    012    import org.junit.Test;
    013    import org.picocontainer.DefaultPicoContainer;
    014    import org.picocontainer.MutablePicoContainer;
    015    import org.picocontainer.behaviors.ImplementationHiding;
    016    import org.picocontainer.injectors.ConstructorInjection;
    017    import org.picocontainer.visitors.VerifyingVisitor;
    018
    019    public class Issue0214TestCase {
    020
    021        // This bug as described in the bug report, http://jira.codehaus.org/browse/PICO-214, cannot be reproduced.
    022        @Test public void testTheBug() {
    023            final MutablePicoContainer pico = new DefaultPicoContainer(new ImplementationHiding().wrap(new ConstructorInjection()));
    024            pico.addComponent(A.class);
    025
    026            /* This is a workaround for the bug described further down. Normally
    027             * this method call should only be needed if specific requirements for
    028             * parameters exist, but not if PicoContainer shall resolve the
    029             * dependencies itself. However, with ImplementationHidingPicoContainer
    030             * this is currently the only way to register a class/interface such
    031             * that the automatic resolution works.
    032             */
    033            pico.addComponent(I1.class, B.class);
    034
    035            /* The following addAdapter(Object, Class) of
    036             * ImplementationHidingPicoContainer is buggy, as it contains
    037             * "ComponentAdapter delegate = componentFactory.createComponentAdapter(componentKey,
    038             * componentImplementation, new Parameter[0]);". Instead of "new
    039             * Parameter[0]" it should be "null" to have a behaviour consistent to
    040             * DefaultPicoContainer, i.e. if PicoContainer shall resolve
    041             * dependencies itself.
    042             */
    043            pico.addComponent(I2.class, C.class);
    044
    045            /* The following verify() throws the exception, but is expected not to
    046             * throw: "org.picocontainer.PicoVerificationException:
    047             * [[org.picocontainer.PicoCompositionException: Either do the
    048             * specified parameters not match any of the following constructors:
    049             * [public PicoContainerBugTest$C(PicoContainerBugTest$A)] or the
    050             * constructors were not accessible for 'class
    051             * PicoContainerBugTest$C']]".
    052             *
    053             * I believe that the error comes this way: In method
    054             * getGreediestSatisfiableConstructor parameters are checked against
    055             * null and if parameters is not null it is assumed that specific
    056             * parameters have been given so that no automatic resolution takes
    057             * place. As now during registration instead of "null" falsly "new
    058             * Parameter[0]" was stored, this is now interpreted as if only the
    059             * nullary constructor shall be used, and if that doesn't exist, the
    060             * exception is thrown.
    061             */
    062            new VerifyingVisitor().traverse(pico);
    063        }
    064
    065        public static interface I1 {
    066        }
    067
    068        public static interface I2 {
    069        }
    070
    071        public static class A {
    072            public A() {
    073            }
    074        }
    075
    076        public static class B implements I1 {
    077            public B(final A a) {
    078            }
    079        }
    080
    081        public static class C implements I2 {
    082            public C(final A a) {
    083            }
    084        }
    085    }