When a non proxied object is beeing eager loaded registry has to instantiate all its constructor parameters. (#35)
If one of these parameters is an eager loaded services (Not yet loaded) registry will create a proxy for it.
Because the proxy is created, that eager load service will not be eager loaded since its already registered as a realized service.
These issue is related with the following
1. https://dev.tapestry.apache.narkive.com/m806StSk/strange-behavour-of-eagerload
2. https://issues.apache.org/jira/browse/TAPESTRY-226.
diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java
index c2233c3..da90942 100644
--- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java
+++ b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java
@@ -116,6 +116,12 @@
*/
private final Map<String, Object> services = CollectionFactory.newCaseInsensitiveMap();
+
+ /**
+ * EagerLoadProxies collection into which proxies for eager loaded services are added. Guarded by BARRIER
+ */
+ private final Collection<EagerLoadServiceProxy> eagerLoadProxies = CollectionFactory.newList();
+
private final Map<String, ServiceDef3> serviceDefs = CollectionFactory.newCaseInsensitiveMap();
/**
@@ -161,7 +167,7 @@
// RegistryImpl should already have checked that the service exists.
assert def != null;
- Object service = findOrCreate(def, null);
+ Object service = findOrCreate(def);
try
{
@@ -225,10 +231,9 @@
* Locates the service proxy for a particular service (from the service definition).
*
* @param def defines the service
- * @param eagerLoadProxies collection into which proxies for eager loaded services are added (or null)
* @return the service proxy
*/
- private Object findOrCreate(final ServiceDef3 def, final Collection<EagerLoadServiceProxy> eagerLoadProxies)
+ private Object findOrCreate(final ServiceDef3 def)
{
final String key = def.getServiceId();
@@ -247,7 +252,7 @@
if (result == null)
{
- result = create(def, eagerLoadProxies);
+ result = create(def);
services.put(key, result);
}
@@ -284,8 +289,16 @@
for (ServiceDef3 def : serviceDefs.values())
{
if (def.isEagerLoad())
- findOrCreate(def, proxies);
+ findOrCreate(def);
}
+
+ BARRIER.withWrite(new Runnable() {
+ @Override
+ public void run() {
+ proxies.addAll(eagerLoadProxies);
+ eagerLoadProxies.clear();
+ }
+ });
}
};
@@ -294,10 +307,8 @@
/**
* Creates the service and updates the cache of created services.
- *
- * @param eagerLoadProxies a list into which any eager loaded proxies should be added
*/
- private Object create(final ServiceDef3 def, final Collection<EagerLoadServiceProxy> eagerLoadProxies)
+ private Object create(final ServiceDef3 def)
{
final String serviceId = def.getServiceId();
@@ -376,11 +387,7 @@
registry.addRegistryShutdownListener(delegate);
- // Occasionally eager load service A may invoke service B from its service builder method; if
- // service B is eager loaded, we'll hit this method but eagerLoadProxies will be null. That's OK
- // ... service B is being realized anyway.
-
- if (def.isEagerLoad() && eagerLoadProxies != null)
+ if (def.isEagerLoad())
eagerLoadProxies.add(delegate);
tracker.setStatus(serviceId, Status.VIRTUAL);
diff --git a/tapestry-ioc/src/test/groovy/ioc/specs/EagerLoadSpec.groovy b/tapestry-ioc/src/test/groovy/ioc/specs/EagerLoadSpec.groovy
index de47abe..73e81b7 100644
--- a/tapestry-ioc/src/test/groovy/ioc/specs/EagerLoadSpec.groovy
+++ b/tapestry-ioc/src/test/groovy/ioc/specs/EagerLoadSpec.groovy
@@ -7,7 +7,9 @@
def "proxied service does eager load"() {
expect:
- EagerProxyReloadModule.eagerLoadServiceDidLoad == false
+ EagerProxyReloadModule.eagerLoadService1DidLoad == false
+ EagerProxyReloadModule.nonProxyEagerLoadServiceDidLoad == false
+ EagerProxyReloadModule.eagerLoadService2DidLoad == false
when:
@@ -17,6 +19,8 @@
then:
- EagerProxyReloadModule.eagerLoadServiceDidLoad == true
+ EagerProxyReloadModule.eagerLoadService1DidLoad == true
+ EagerProxyReloadModule.nonProxyEagerLoadServiceDidLoad == true
+ EagerProxyReloadModule.eagerLoadService2DidLoad == true
}
}
diff --git a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/EagerLoadService.java b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/EagerLoadService1.java
similarity index 94%
copy from tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/EagerLoadService.java
copy to tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/EagerLoadService1.java
index 808fb8c..2cce573 100644
--- a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/EagerLoadService.java
+++ b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/EagerLoadService1.java
@@ -14,7 +14,7 @@
package org.apache.tapestry5.ioc.test;
-public interface EagerLoadService
+public interface EagerLoadService1
{
}
diff --git a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/EagerLoadServiceImpl.java b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/EagerLoadService1Impl.java
similarity index 81%
rename from tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/EagerLoadServiceImpl.java
rename to tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/EagerLoadService1Impl.java
index d2274d0..8217db3 100644
--- a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/EagerLoadServiceImpl.java
+++ b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/EagerLoadService1Impl.java
@@ -17,10 +17,10 @@
import org.apache.tapestry5.ioc.annotations.EagerLoad;
@EagerLoad
-public class EagerLoadServiceImpl implements EagerLoadService
+public class EagerLoadService1Impl implements EagerLoadService1
{
- public EagerLoadServiceImpl()
+ public EagerLoadService1Impl()
{
- EagerProxyReloadModule.eagerLoadServiceDidLoad = true;
+ EagerProxyReloadModule.eagerLoadService1DidLoad = true;
}
}
diff --git a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/EagerLoadService.java b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/EagerLoadService2.java
similarity index 94%
rename from tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/EagerLoadService.java
rename to tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/EagerLoadService2.java
index 808fb8c..0209825 100644
--- a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/EagerLoadService.java
+++ b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/EagerLoadService2.java
@@ -14,7 +14,7 @@
package org.apache.tapestry5.ioc.test;
-public interface EagerLoadService
+public interface EagerLoadService2
{
}
diff --git a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/EagerLoadServiceImpl.java b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/EagerLoadService2Impl.java
similarity index 74%
copy from tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/EagerLoadServiceImpl.java
copy to tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/EagerLoadService2Impl.java
index d2274d0..24f60a8 100644
--- a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/EagerLoadServiceImpl.java
+++ b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/EagerLoadService2Impl.java
@@ -14,13 +14,11 @@
package org.apache.tapestry5.ioc.test;
-import org.apache.tapestry5.ioc.annotations.EagerLoad;
-@EagerLoad
-public class EagerLoadServiceImpl implements EagerLoadService
+public class EagerLoadService2Impl implements EagerLoadService2
{
- public EagerLoadServiceImpl()
+ public EagerLoadService2Impl()
{
- EagerProxyReloadModule.eagerLoadServiceDidLoad = true;
+ EagerProxyReloadModule.eagerLoadService2DidLoad = true;
}
}
diff --git a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/EagerProxyReloadModule.java b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/EagerProxyReloadModule.java
index 1ba7d39..5375fa7 100644
--- a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/EagerProxyReloadModule.java
+++ b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/EagerProxyReloadModule.java
@@ -16,12 +16,17 @@
import org.apache.tapestry5.ioc.ServiceBinder;
+//@ImportModule(EagerProxy2ReloadModule.class)
public class EagerProxyReloadModule
{
- public static boolean eagerLoadServiceDidLoad;
+ public static boolean eagerLoadService1DidLoad;
+ public static boolean nonProxyEagerLoadServiceDidLoad;
+ public static boolean eagerLoadService2DidLoad;
public static void bind(ServiceBinder binder)
{
- binder.bind(EagerLoadService.class, EagerLoadServiceImpl.class);
+ binder.bind(EagerLoadService1.class, EagerLoadService1Impl.class);
+ binder.bind(NonProxiedEagerLoadService.class).eagerLoad();
+ binder.bind(EagerLoadService2.class, EagerLoadService2Impl.class).eagerLoad();
}
}
diff --git a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/NonProxiedEagerLoadService.java b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/NonProxiedEagerLoadService.java
new file mode 100644
index 0000000..60d716d
--- /dev/null
+++ b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/NonProxiedEagerLoadService.java
@@ -0,0 +1,7 @@
+package org.apache.tapestry5.ioc.test;
+
+public class NonProxiedEagerLoadService {
+ public NonProxiedEagerLoadService(EagerLoadService2 service2) {
+ EagerProxyReloadModule.nonProxyEagerLoadServiceDidLoad = true;
+ }
+}