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 2008/03/19 03:24:34 UTC

svn commit: r638683 - in /tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal: Module.java ModuleImpl.java RegistryImpl.java

Author: hlship
Date: Tue Mar 18 19:24:33 2008
New Revision: 638683

URL: http://svn.apache.org/viewvc?rev=638683&view=rev
Log:
TAPESTRY-2267: Services that are dependencies of other EagerLoad services may not be eagerly loaded

Modified:
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/Module.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ModuleImpl.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RegistryImpl.java

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/Module.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/Module.java?rev=638683&r1=638682&r2=638683&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/Module.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/Module.java Tue Mar 18 19:24:33 2008
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007 The Apache Software Foundation
+// Copyright 2006, 2007, 2008 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.
@@ -25,9 +25,8 @@
 import java.util.Set;
 
 /**
- * A module within the Tapestry IoC registry. Each Module is constructed around a corresponding
- * module builder instance; the methods and annotations of that instance define the services
- * provided by the module.
+ * A module within the Tapestry IoC registry. Each Module is constructed around a corresponding module builder instance;
+ * the methods and annotations of that instance define the services provided by the module.
  */
 public interface Module extends ModuleBuilderSource
 {
@@ -43,9 +42,8 @@
     <T> T getService(String serviceId, Class<T> serviceInterface);
 
     /**
-     * Locates the ids of all services that implement the provided service interface, or whose
-     * service interface is assignable to the provided service interface (is a super-class or
-     * super-interface).
+     * Locates the ids of all services that implement the provided service interface, or whose service interface is
+     * assignable to the provided service interface (is a super-class or super-interface).
      *
      * @param serviceInterface the interface to search for
      * @return a collection of service ids
@@ -53,11 +51,10 @@
     Collection<String> findServiceIdsForInterface(Class serviceInterface);
 
     /**
-     * Locates all the decorators that should apply the identified service. This includes visibility
-     * rules (private services may only be decorated by decorators in the same module) and other
-     * filtering rules. The resulting list is ordered and from the list of
-     * {@link org.apache.tapestry.ioc.def.DecoratorDef}s, a list of {@link ServiceDecorator}s is
-     * returned.
+     * Locates all the decorators that should apply the identified service. This includes visibility rules (private
+     * services may only be decorated by decorators in the same module) and other filtering rules. The resulting list is
+     * ordered and from the list of {@link org.apache.tapestry.ioc.def.DecoratorDef}s, a list of {@link
+     * ServiceDecorator}s is returned.
      *
      * @param serviceId identifies the service to be decorated
      * @return the ordered list of service decorators
@@ -65,8 +62,8 @@
     List<ServiceDecorator> findDecoratorsForService(String serviceId);
 
     /**
-     * Iterates over any decorator definitions defined by the module and returns those that apply to
-     * the provided service definition.
+     * Iterates over any decorator definitions defined by the module and returns those that apply to the provided
+     * service definition.
      *
      * @param serviceDef for which decorators are being assembled
      * @return set of decorators, possibly empty (but not null)
@@ -79,10 +76,12 @@
     Set<ContributionDef> getContributorDefsForService(String serviceId);
 
     /**
-     * Locates services with the {@link org.apache.tapestry.ioc.annotations.EagerLoad} annotation
-     * and forces them to instantiate fully. This is part of the Registry startup.
+     * Locates services with the {@link org.apache.tapestry.ioc.annotations.EagerLoad} annotation and generates proxies
+     * for them, then adds them to the proxies list for instantiation.
+     *
+     * @param proxies collection of proxies to which any eager load services in the module should be added
      */
-    void eagerLoadServices();
+    void collectEagerLoadServices(Collection<EagerLoadServiceProxy> proxies);
 
     /**
      * Returns the service definition for the given service id.
@@ -93,8 +92,8 @@
     ServiceDef getServiceDef(String serviceId);
 
     /**
-     * Returns the name used to obtain a logger for the module. Services within the module suffix
-     * this with a period and the service id.
+     * Returns the name used to obtain a logger for the module. Services within the module suffix this with a period and
+     * the service id.
      *
      * @return module logger name
      */

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ModuleImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ModuleImpl.java?rev=638683&r1=638682&r2=638683&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ModuleImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ModuleImpl.java Tue Mar 18 19:24:33 2008
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007 The Apache Software Foundation
+// Copyright 2006, 2007, 2008 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.
@@ -51,9 +51,9 @@
     private Object _moduleBuilder;
 
     /**
-     * A single mutex, shared by all modules, that serializes creation of services across all
-     * threads. This is a bit draconian, but appears to be necessary. Fortunately, service creation
-     * is a very tiny part of any individual service's lifecycle.
+     * A single mutex, shared by all modules, that serializes creation of services across all threads. This is a bit
+     * draconian, but appears to be necessary. Fortunately, service creation is a very tiny part of any individual
+     * service's lifecycle.
      */
     private static final Object MUTEX = new Object();
 
@@ -150,7 +150,7 @@
      * @param eagerLoadProxies TODO
      * @return the service proxy
      */
-    private Object findOrCreate(ServiceDef def, List<EagerLoadServiceProxy> eagerLoadProxies)
+    private Object findOrCreate(ServiceDef def, Collection<EagerLoadServiceProxy> eagerLoadProxies)
     {
         synchronized (MUTEX)
         {
@@ -168,10 +168,8 @@
         }
     }
 
-    public void eagerLoadServices()
+    public void collectEagerLoadServices(Collection<EagerLoadServiceProxy> proxies)
     {
-        List<EagerLoadServiceProxy> proxies = newList();
-
         synchronized (MUTEX)
         {
             for (String serviceId : _moduleDef.getServiceIds())
@@ -180,19 +178,15 @@
 
                 if (def.isEagerLoad()) findOrCreate(def, proxies);
             }
-
-            for (EagerLoadServiceProxy proxy : proxies)
-                proxy.eagerLoadService();
         }
     }
 
     /**
-     * Creates the service and updates the cache of created services. Access is synchronized via
-     * {@link #MUTEX}.
+     * Creates the service and updates the cache of created services. Access is synchronized via {@link #MUTEX}.
      *
      * @param eagerLoadProxies a list into which any eager loaded proxies should be added
      */
-    private Object create(ServiceDef def, List<EagerLoadServiceProxy> eagerLoadProxies)
+    private Object create(ServiceDef def, Collection<EagerLoadServiceProxy> eagerLoadProxies)
     {
         String serviceId = def.getServiceId();
 
@@ -351,7 +345,7 @@
         classFab.addField("_creator", Modifier.PRIVATE | Modifier.FINAL, ObjectCreator.class);
         classFab.addField("_token", Modifier.PRIVATE | Modifier.FINAL, ServiceProxyToken.class);
 
-        classFab.addConstructor(new Class[]{ObjectCreator.class, ServiceProxyToken.class}, null,
+        classFab.addConstructor(new Class[] { ObjectCreator.class, ServiceProxyToken.class }, null,
                                 "{ _creator = $1; _token = $2; }");
 
         // Make proxies serializable by writing the token to the stream.
@@ -361,7 +355,7 @@
         // This is the "magic" signature that allows an object to substitute some other
         // object for itself.
         MethodSignature writeReplaceSig = new MethodSignature(Object.class, "writeReplace", null,
-                                                              new Class[]{ObjectStreamException.class});
+                                                              new Class[] { ObjectStreamException.class });
 
         classFab.addMethod(Modifier.PRIVATE, writeReplaceSig, "return _token;");
 

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RegistryImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RegistryImpl.java?rev=638683&r1=638682&r2=638683&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RegistryImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/RegistryImpl.java Tue Mar 18 19:24:33 2008
@@ -55,8 +55,8 @@
     }
 
     /**
-     * Used to obtain the {@link org.apache.tapestry.ioc.services.ClassFactory} service, which is
-     * crucial when creating runtime classes for proxies and the like.
+     * Used to obtain the {@link org.apache.tapestry.ioc.services.ClassFactory} service, which is crucial when creating
+     * runtime classes for proxies and the like.
      */
     static final String CLASS_FACTORY_SERVICE_ID = "ClassFactory";
 
@@ -191,17 +191,23 @@
     }
 
     /**
-     * It's not unreasonable for an eagerly-loaded service to decide to start a thread, at which
-     * point we raise issues about improper publishing of the Registry instance from the
-     * RegistryImpl constructor. Moving eager loading of services out to its own method should
-     * ensure thread safety.
+     * It's not unreasonable for an eagerly-loaded service to decide to start a thread, at which point we raise issues
+     * about improper publishing of the Registry instance from the RegistryImpl constructor. Moving eager loading of
+     * services out to its own method should ensure thread safety.
      */
     public void performRegistryStartup()
     {
         _eagerLoadLock.lock();
 
+        List<EagerLoadServiceProxy> proxies = CollectionFactory.newList();
+
         for (Module m : _modules)
-            m.eagerLoadServices();
+            m.collectEagerLoadServices(proxies);
+
+        // TAPESTRY-2267: Gather up all the proxies before instantiating any of them.
+
+        for (EagerLoadServiceProxy proxy : proxies)
+            proxy.eagerLoadService();
 
         getService("RegistryStartup", Runnable.class).run();