You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2010/03/27 02:24:07 UTC

svn commit: r928115 - in /tapestry/tapestry5/trunk/tapestry-ioc/src: main/java/org/apache/tapestry5/ioc/ main/java/org/apache/tapestry5/ioc/internal/ test/java/org/apache/tapestry5/ioc/

Author: hlship
Date: Sat Mar 27 01:24:07 2010
New Revision: 928115

URL: http://svn.apache.org/viewvc?rev=928115&view=rev
Log:
TAP5-1050: Injecting a Logger into a non-service object, created as part of constructing a service configuration, should work but doesn't

Added:
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/IndirectResources.java   (with props)
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/InjectionCheck.java   (with props)
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/InjectionCheckImpl.java   (with props)
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/InjectionCheckModule.java   (with props)
Modified:
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/ObjectLocator.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/AbstractServiceCreator.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ContributionDefImpl.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/IntegrationTest.java

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/ObjectLocator.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/ObjectLocator.java?rev=928115&r1=928114&r2=928115&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/ObjectLocator.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/ObjectLocator.java Sat Mar 27 01:24:07 2010
@@ -83,9 +83,12 @@ public interface ObjectLocator
     <T> T getObject(Class<T> objectType, AnnotationProvider annotationProvider);
 
     /**
-     * Autobuilds a class by finding the public constructor with the most parameters. Services and
-     * resources will be
-     * injected into the parameters of the constructor and private field marked with the {@link Inject} annotation.
+     * Autobuilds a class by finding the public constructor with the most parameters. Services and other resources or
+     * dependencies will be injected into the parameters of the constructor and private field marked with the
+     * {@link Inject} annotation. There are two cases: constructing a service implementation, and constructing
+     * an arbitrary object. In the former case, many <em>service resources</em> are also available for injection, not
+     * just dependencies or objects provided via
+     * {@link MasterObjectProvider#provide(Class, AnnotationProvider, ObjectLocator, boolean)}.
      * 
      * @param <T>
      * @param clazz
@@ -98,10 +101,8 @@ public interface ObjectLocator
     <T> T autobuild(Class<T> clazz);
 
     /**
-     * Autobuilds a class by finding the public constructor with the most parameters. Services and
-     * resources will be
-     * injected into the parameters of the constructor and private field marked with the {@link Inject} annotation. This
-     * version tracks the operation using {@link OperationTracker#invoke(String, Invokable)}.
+     * Preferred version of {@link #autobuild(Class)} that tracks the operation using
+     * {@link OperationTracker#invoke(String, Invokable)}.
      * 
      * @param <T>
      * @param description
@@ -133,6 +134,7 @@ public interface ObjectLocator
      * @param implementationClass
      *            a concrete class that implements the interface
      * @return a proxy
+     * @see #autobuild(Class)
      */
     <T> T proxy(Class<T> interfaceClass, Class<? extends T> implementationClass);
 }

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/AbstractServiceCreator.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/AbstractServiceCreator.java?rev=928115&r1=928114&r2=928115&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/AbstractServiceCreator.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/AbstractServiceCreator.java Sat Mar 27 01:24:07 2010
@@ -69,7 +69,7 @@ public abstract class AbstractServiceCre
     }
 
     /**
-     * Returns a map (based on parameterDefaults) that includes (possibly) an additional mapping containing the
+     * Returns a map (based on injectionResources) that includes (possibly) an additional mapping containing the
      * collected configuration data. This involves scanning the parameters and generic types.
      */
     protected final InjectionResources createInjectionResources()
@@ -115,9 +115,11 @@ public abstract class AbstractServiceCre
         return new DelegatingInjectionResources(core, configurations);
     }
 
+    @SuppressWarnings("unchecked")
     private List getOrderedConfiguration(Type genericType)
     {
         Class valueType = findParameterizedTypeFromGenericType(genericType);
+        
         return resources.getOrderedConfiguration(valueType);
     }
 

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ContributionDefImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ContributionDefImpl.java?rev=928115&r1=928114&r2=928115&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ContributionDefImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ContributionDefImpl.java Sat Mar 27 01:24:07 2010
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007, 2008, 2009 The Apache Software Foundation
+// Copyright 2006, 2007, 2008, 2009, 2010 The Apache Software Foundation
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -14,17 +14,26 @@
 
 package org.apache.tapestry5.ioc.internal;
 
-import org.apache.tapestry5.ioc.*;
-import org.apache.tapestry5.ioc.def.ContributionDef;
-import org.apache.tapestry5.ioc.def.ContributionDef2;
-import org.apache.tapestry5.ioc.internal.util.*;
-import org.apache.tapestry5.ioc.services.ClassFactory;
-
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.Map;
 import java.util.Set;
-import java.util.logging.Logger;
+
+import org.apache.tapestry5.ioc.Configuration;
+import org.apache.tapestry5.ioc.MappedConfiguration;
+import org.apache.tapestry5.ioc.ModuleBuilderSource;
+import org.apache.tapestry5.ioc.ObjectLocator;
+import org.apache.tapestry5.ioc.OrderedConfiguration;
+import org.apache.tapestry5.ioc.ServiceResources;
+import org.apache.tapestry5.ioc.def.ContributionDef2;
+import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry5.ioc.internal.util.DelegatingInjectionResources;
+import org.apache.tapestry5.ioc.internal.util.InjectionResources;
+import org.apache.tapestry5.ioc.internal.util.InternalUtils;
+import org.apache.tapestry5.ioc.internal.util.MapInjectionResources;
+import org.apache.tapestry5.ioc.internal.util.WrongConfigurationTypeGuard;
+import org.apache.tapestry5.ioc.services.ClassFactory;
+import org.slf4j.Logger;
 
 public class ContributionDefImpl implements ContributionDef2
 {

Added: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/IndirectResources.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/IndirectResources.java?rev=928115&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/IndirectResources.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/IndirectResources.java Sat Mar 27 01:24:07 2010
@@ -0,0 +1,40 @@
+// Copyright 2010 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.ioc;
+
+import org.slf4j.Logger;
+
+public class IndirectResources
+{
+    private final Logger logger;
+
+    private final ServiceResources serviceResources;
+
+    public IndirectResources(Logger logger, ServiceResources resources)
+    {
+        this.logger = logger;
+        this.serviceResources = resources;
+    }
+
+    public Logger getLogger()
+    {
+        return logger;
+    }
+
+    public ServiceResources getResources()
+    {
+        return serviceResources;
+    }
+}

Propchange: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/IndirectResources.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/InjectionCheck.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/InjectionCheck.java?rev=928115&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/InjectionCheck.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/InjectionCheck.java Sat Mar 27 01:24:07 2010
@@ -0,0 +1,24 @@
+// Copyright 2010 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.ioc;
+
+import org.slf4j.Logger;
+
+public interface InjectionCheck
+{
+    Logger getLogger();
+
+    Object getValue(String key);
+}

Propchange: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/InjectionCheck.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/InjectionCheckImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/InjectionCheckImpl.java?rev=928115&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/InjectionCheckImpl.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/InjectionCheckImpl.java Sat Mar 27 01:24:07 2010
@@ -0,0 +1,44 @@
+// Copyright 2010 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.ioc;
+
+import java.util.Map;
+
+import org.slf4j.Logger;
+
+public class InjectionCheckImpl implements InjectionCheck
+{
+
+    private final Logger logger;
+
+    private final Map<String, Object> configuration;
+
+    public InjectionCheckImpl(Logger logger, Map<String, Object> configuration)
+    {
+        this.logger = logger;
+        this.configuration = configuration;
+    }
+
+    public Logger getLogger()
+    {
+        return logger;
+    }
+
+    public Object getValue(String key)
+    {
+        return configuration.get(key);
+    }
+
+}

Propchange: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/InjectionCheckImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/InjectionCheckModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/InjectionCheckModule.java?rev=928115&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/InjectionCheckModule.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/InjectionCheckModule.java Sat Mar 27 01:24:07 2010
@@ -0,0 +1,35 @@
+// Copyright 2010 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.ioc;
+
+import org.slf4j.Logger;
+
+/**
+ * Used to check the ability to inject service resources (including Logger) into
+ * contribut methods, etc.
+ */
+public class InjectionCheckModule
+{
+    public static void bind(ServiceBinder binder)
+    {
+        binder.bind(InjectionCheck.class);
+    }
+
+    public static void contributeInjectionCheck(MappedConfiguration<String, Object> configuration, Logger logger)
+    {
+        configuration.add("logger", logger);
+        configuration.addInstance("indirect-resources", IndirectResources.class);
+    }
+}

Propchange: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/InjectionCheckModule.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/IntegrationTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/IntegrationTest.java?rev=928115&r1=928114&r2=928115&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/IntegrationTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/IntegrationTest.java Sat Mar 27 01:24:07 2010
@@ -4,7 +4,7 @@
 // you may not use this file except in compliance with the License.
 // You may obtain a copy of the License at
 //
-//     http://www.apache.org/licenses/LICENSE-2.0
+// http://www.apache.org/licenses/LICENSE-2.0
 //
 // Unless required by applicable law or agreed to in writing, software
 // distributed under the License is distributed on an "AS IS" BASIS,
@@ -270,8 +270,7 @@ public class IntegrationTest extends IOC
         }
         catch (Exception ex)
         {
-            assertMessageContains(
-                    ex,
+            assertMessageContains(ex,
                     "Error building service proxy for service 'ScopeRequiresAProxyAndNoInterfaceIsProvided'",
                     "Service scope 'perthread' requires a proxy");
         }
@@ -375,8 +374,7 @@ public class IntegrationTest extends IOC
     {
         Registry r = buildRegistry(EagerLoadModule.class);
 
-        assertFalse(EagerLoadModule._eagerLoadDidHappen,
-                "EagerLoadModule is not in correct initial state.");
+        assertFalse(EagerLoadModule._eagerLoadDidHappen, "EagerLoadModule is not in correct initial state.");
 
         r.performRegistryStartup();
 
@@ -425,12 +423,8 @@ public class IntegrationTest extends IOC
         }
         catch (RuntimeException ex)
         {
-            assertMessageContains(
-                    ex,
-                    "Error invoking constructor",
-                    "ExceptionInConstructorServiceImpl()",
-                    "for service 'Pingable'", 
-                    "Yes, we have no tomatoes.");
+            assertMessageContains(ex, "Error invoking constructor", "ExceptionInConstructorServiceImpl()",
+                    "for service 'Pingable'", "Yes, we have no tomatoes.");
         }
 
         r.shutdown();
@@ -475,8 +469,8 @@ public class IntegrationTest extends IOC
         }
         catch (RuntimeException ex)
         {
-            assertMessageContains(ex, "No service implements the interface "
-                    + StringTransformer.class.getName() + ". Please provide");
+            assertMessageContains(ex, "No service implements the interface " + StringTransformer.class.getName()
+                    + ". Please provide");
         }
     }
 
@@ -490,8 +484,7 @@ public class IntegrationTest extends IOC
         }
         catch (RuntimeException ex)
         {
-            assertMessageContains(ex, "No service implements the interface "
-                    + Pingable.class.getName());
+            assertMessageContains(ex, "No service implements the interface " + Pingable.class.getName());
         }
     }
 
@@ -567,14 +560,12 @@ public class IntegrationTest extends IOC
         }
         catch (RuntimeException ex)
         {
-            assertMessageContains(
-                    ex,
+            assertMessageContains(ex,
                     "Class org.apache.tapestry5.ioc.UnbuildablePingable does not contain a public constructor needed to autobuild.");
 
             // Like to check that the message includes the source location
 
-            assertTrue(ex.getMessage().matches(
-                    ".*\\(at ServiceBuilderAutobuilderModule.java:\\d+\\).*"));
+            assertTrue(ex.getMessage().matches(".*\\(at ServiceBuilderAutobuilderModule.java:\\d+\\).*"));
         }
 
         r.shutdown();
@@ -593,8 +584,7 @@ public class IntegrationTest extends IOC
         }
         catch (RuntimeException ex)
         {
-            assertMessageContains(
-                    ex,
+            assertMessageContains(ex,
                     "Class org.apache.tapestry5.ioc.UnbuildablePingable does not contain a public constructor needed to autobuild.");
         }
 
@@ -614,8 +604,7 @@ public class IntegrationTest extends IOC
         }
         catch (RuntimeException ex)
         {
-            assertMessageContains(
-                    ex,
+            assertMessageContains(ex,
                     "Error invoking constructor org.apache.tapestry5.ioc.FailInConstructorRunnable()",
                     "Failure in Runnable constructor.");
 
@@ -658,8 +647,7 @@ public class IntegrationTest extends IOC
         }
         catch (RuntimeException ex)
         {
-            assertEquals(ex.getMessage(),
-                    "No service implements the interface java.sql.PreparedStatement.");
+            assertEquals(ex.getMessage(), "No service implements the interface java.sql.PreparedStatement.");
         }
 
         r.shutdown();
@@ -946,8 +934,7 @@ public class IntegrationTest extends IOC
     {
         File fakejar = new File("src/test/fakejar");
 
-        assertTrue(fakejar.exists() && fakejar.isDirectory(),
-                "src/test/fakejar must be an existing directory");
+        assertTrue(fakejar.exists() && fakejar.isDirectory(), "src/test/fakejar must be an existing directory");
 
         URL url = fakejar.toURL();
 
@@ -1009,8 +996,7 @@ public class IntegrationTest extends IOC
         }
         catch (RuntimeException ex)
         {
-            assertMessageContains(ex,
-                    "Construction of service 'TypeCoercer' has failed due to recursion");
+            assertMessageContains(ex, "Construction of service 'TypeCoercer' has failed due to recursion");
         }
 
         r.shutdown();
@@ -1029,8 +1015,7 @@ public class IntegrationTest extends IOC
         }
         catch (RuntimeException ex)
         {
-            assertMessageContains(
-                    ex,
+            assertMessageContains(ex,
                     "Module class org.apache.tapestry5.ioc.internal.PrivateConstructorModule does not contain any public constructors.");
         }
     }
@@ -1131,8 +1116,7 @@ public class IntegrationTest extends IOC
         }
         catch (RuntimeException ex)
         {
-            assertMessageContains(
-                    ex,
+            assertMessageContains(ex,
                     "Unable to determine resource value to inject into field 'unknownRunnable' (of type java.lang.Runnable).");
         }
     }
@@ -1183,8 +1167,7 @@ public class IntegrationTest extends IOC
         }
         catch (RuntimeException ex)
         {
-            assertMessageContains(
-                    ex,
+            assertMessageContains(ex,
                     "Module class org.apache.tapestry5.ioc.ExtraMethodsModule contains unrecognized public methods: ",
                     "thisMethodIsInvalid()", "soIsThisMethod().");
         }
@@ -1241,8 +1224,7 @@ public class IntegrationTest extends IOC
     @Test
     public void successful_ordered_configuration_override()
     {
-        Registry r = buildRegistry(FredModule.class, BarneyModule.class,
-                ConfigurationOverrideModule.class);
+        Registry r = buildRegistry(FredModule.class, BarneyModule.class, ConfigurationOverrideModule.class);
 
         NameListHolder service = r.getService("OrderedNames", NameListHolder.class);
 
@@ -1257,8 +1239,7 @@ public class IntegrationTest extends IOC
     @Test
     public void failed_ordered_configuration_override()
     {
-        Registry r = buildRegistry(FredModule.class, BarneyModule.class,
-                FailedConfigurationOverrideModule.class);
+        Registry r = buildRegistry(FredModule.class, BarneyModule.class, FailedConfigurationOverrideModule.class);
 
         NameListHolder service = r.getService("OrderedNames", NameListHolder.class);
 
@@ -1282,8 +1263,8 @@ public class IntegrationTest extends IOC
     @Test
     public void duplicate_ordered_configuration_override()
     {
-        Registry r = buildRegistry(FredModule.class, BarneyModule.class,
-                ConfigurationOverrideModule.class, DuplicateConfigurationOverrideModule.class);
+        Registry r = buildRegistry(FredModule.class, BarneyModule.class, ConfigurationOverrideModule.class,
+                DuplicateConfigurationOverrideModule.class);
 
         NameListHolder service = r.getService("OrderedNames", NameListHolder.class);
 
@@ -1306,8 +1287,7 @@ public class IntegrationTest extends IOC
     @Test
     public void mapped_configuration_override()
     {
-        Registry r = buildRegistry(FredModule.class, BarneyModule.class,
-                ConfigurationOverrideModule.class);
+        Registry r = buildRegistry(FredModule.class, BarneyModule.class, ConfigurationOverrideModule.class);
 
         StringLookup sl = r.getService(StringLookup.class);
 
@@ -1351,8 +1331,8 @@ public class IntegrationTest extends IOC
     @Test
     public void duplicate_override_for_mapped_configuration()
     {
-        Registry r = buildRegistry(FredModule.class, BarneyModule.class,
-                ConfigurationOverrideModule.class, DuplicateConfigurationOverrideModule.class);
+        Registry r = buildRegistry(FredModule.class, BarneyModule.class, ConfigurationOverrideModule.class,
+                DuplicateConfigurationOverrideModule.class);
 
         StringLookup sl = r.getService(StringLookup.class);
 
@@ -1414,8 +1394,7 @@ public class IntegrationTest extends IOC
         }
         catch (RuntimeException ex)
         {
-            assertMessageContains(
-                    ex,
+            assertMessageContains(ex,
                     "Advise method org.apache.tapestry5.ioc.AdviceMethodMissingAdvisorParameterModule.adviseBar()",
                     "must take a parameter of type org.apache.tapestry5.ioc.MethodAdviceReceiver.");
         }
@@ -1433,7 +1412,7 @@ public class IntegrationTest extends IOC
 
         assertEquals(g.getGreeting(), "ADVICE IS EASY!");
     }
-    
+
     @Test
     public void contribute_by_annotation()
     {
@@ -1442,21 +1421,21 @@ public class IntegrationTest extends IOC
         NameListHolder greek = r.getService("Greek", NameListHolder.class);
 
         assertEquals(greek.getNames(), Arrays.asList("Alpha", "Beta", "Gamma", "Delta"));
-        
+
         NameListHolder anotherGreek = r.getService("AnotherGreek", NameListHolder.class);
-        
+
         assertEquals(anotherGreek.getNames(), Arrays.asList("Alpha", "Beta", "Gamma", "Delta", "Epsilon"));
-        
+
         NameListHolder hebrew = r.getService("Hebrew", NameListHolder.class);
-        
+
         assertEquals(hebrew.getNames(), Arrays.asList("Alef", "Bet", "Gimel", "Dalet", "He", "Vav"));
-        
+
         NameListHolder2 holder = r.getService("ServiceWithEmptyConfiguration", NameListHolder2.class);
-        
+
         assertEquals(holder.getNames(), Arrays.asList());
-        
+
     }
-    
+
     @Test
     public void contribute_by_annotation_to_nonexistent_service()
     {
@@ -1465,19 +1444,17 @@ public class IntegrationTest extends IOC
             buildRegistry(InvalidContributeDefModule2.class);
             unreachable();
         }
-        catch (Exception e) 
+        catch (Exception e)
         {
             assertMessageContains(
-                e,
-                "Contribution org.apache.tapestry5.ioc.InvalidContributeDefModule2.provideConfiguration(OrderedConfiguration)",
-                "is for service 'interface org.apache.tapestry5.ioc.NameListHolder'",
-                "qualified with marker annotations [",
-                "interface org.apache.tapestry5.ioc.BlueMarker", 
-                "interface org.apache.tapestry5.ioc.RedMarker",
-                "], which does not exist.");
+                    e,
+                    "Contribution org.apache.tapestry5.ioc.InvalidContributeDefModule2.provideConfiguration(OrderedConfiguration)",
+                    "is for service 'interface org.apache.tapestry5.ioc.NameListHolder'",
+                    "qualified with marker annotations [", "interface org.apache.tapestry5.ioc.BlueMarker",
+                    "interface org.apache.tapestry5.ioc.RedMarker", "], which does not exist.");
         }
     }
-    
+
     @Test
     public void contribute_by_annotation_wrong_marker()
     {
@@ -1486,13 +1463,30 @@ public class IntegrationTest extends IOC
             buildRegistry(InvalidContributeDefModule3.class);
             unreachable();
         }
-        catch (Exception e) 
+        catch (Exception e)
         {
             assertMessageContains(
-                e,
-                "Contribution org.apache.tapestry5.ioc.InvalidContributeDefModule3.provideConfiguration(OrderedConfiguration)",
-                "is for service 'interface org.apache.tapestry5.ioc.NameListHolder'",
-                "qualified with marker annotations [interface org.apache.tapestry5.ioc.BlueMarker], which does not exist.");
+                    e,
+                    "Contribution org.apache.tapestry5.ioc.InvalidContributeDefModule3.provideConfiguration(OrderedConfiguration)",
+                    "is for service 'interface org.apache.tapestry5.ioc.NameListHolder'",
+                    "qualified with marker annotations [interface org.apache.tapestry5.ioc.BlueMarker], which does not exist.");
         }
     }
+
+    @Test
+    public void service_resources_available_when_invoking_contribute_method()
+    {
+        Registry r = buildRegistry(InjectionCheckModule.class);
+
+        InjectionCheck service = r.getService(InjectionCheck.class);
+
+        assertSame(service.getLogger(), service.getValue("logger"));
+
+        IndirectResources il = (IndirectResources) service.getValue("indirect-resources");
+
+        assertSame(service.getLogger(), il.getLogger());
+        assertSame(service.getLogger(), il.getResources().getLogger());
+
+        r.shutdown();
+    }
 }