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 }