You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2007/11/17 17:36:52 UTC
svn commit: r595970 [1/2] - in /tapestry/tapestry5/trunk/tapestry-ioc/src:
main/java/org/apache/tapestry/ioc/internal/
main/java/org/apache/tapestry/ioc/test/
main/resources/org/apache/tapestry/ioc/internal/
main/resources/org/apache/tapestry/ioc/inter...
Author: hlship
Date: Sat Nov 17 08:36:50 2007
New Revision: 595970
URL: http://svn.apache.org/viewvc?rev=595970&view=rev
Log:
TAPESTRY-1891: Tapestry IoC Service Proxies should be serializable
Added:
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/SerializationSupport.java
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceProxyProvider.java
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceProxyToken.java
tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/serialization.apt
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ServiceProxySerializationTest.java
Modified:
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/IOCInternalTestCase.java
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/IOCMessages.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
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/test/IOCTestCase.java
tapestry/tapestry5/trunk/tapestry-ioc/src/main/resources/org/apache/tapestry/ioc/internal/IOCStrings.properties
tapestry/tapestry5/trunk/tapestry-ioc/src/main/resources/org/apache/tapestry/ioc/internal/services/ServiceStrings.properties
tapestry/tapestry5/trunk/tapestry-ioc/src/site/site.xml
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/IntegrationTest.java
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/RegistryBuilderTest.java
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/DefaultModuleDefImplTest.java
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ModuleImplTest.java
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/PropertyAccessImplTest.java
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/services/RegistryStartupTest.java
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/services/PropertyShadowBuilderImplTest.java
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/IOCInternalTestCase.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/IOCInternalTestCase.java?rev=595970&r1=595969&r2=595970&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/IOCInternalTestCase.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/IOCInternalTestCase.java Sat Nov 17 08:36:50 2007
@@ -91,6 +91,7 @@
throw new UnsupportedOperationException("No registry shutdown until @AfterSuite.");
}
+
@AfterSuite
public final void shutdown_registry()
{
@@ -133,14 +134,13 @@
expect(source.getDescription()).andReturn(description).atLeastOnce();
}
- protected final void train_getLifecycle(InternalRegistry registry, String scope,
- ServiceLifecycle lifecycle)
+ protected final void train_getLifecycle(InternalRegistry registry, String scope, ServiceLifecycle lifecycle)
{
expect(registry.getServiceLifecycle(scope)).andReturn(lifecycle);
}
- protected final <T> void train_getService(InternalRegistry registry, String serviceId,
- Class<T> serviceInterface, T service)
+ protected final <T> void train_getService(InternalRegistry registry, String serviceId, Class<T> serviceInterface,
+ T service)
{
expect(registry.getService(serviceId, serviceInterface)).andReturn(service);
}
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/IOCMessages.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/IOCMessages.java?rev=595970&r1=595969&r2=595970&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/IOCMessages.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/IOCMessages.java Sat Nov 17 08:36:50 2007
@@ -56,14 +56,10 @@
return MESSAGES.get("builder-locked");
}
- static String serviceWrongInterface(String serviceId, Class actualInterface,
- Class requestedInterface)
+ static String serviceWrongInterface(String serviceId, Class actualInterface, Class requestedInterface)
{
- return MESSAGES.format(
- "service-wrong-interface",
- serviceId,
- actualInterface.getName(),
- requestedInterface.getName());
+ return MESSAGES.format("service-wrong-interface", serviceId, actualInterface.getName(),
+ requestedInterface.getName());
}
static String instantiateBuilderError(Class builderClass, Throwable cause)
@@ -107,11 +103,7 @@
buffer.append(ids.get(i));
}
- return MESSAGES.format(
- "many-service-matches",
- serviceInterface.getName(),
- ids.size(),
- buffer.toString());
+ return MESSAGES.format("many-service-matches", serviceInterface.getName(), ids.size(), buffer.toString());
}
static String unknownScope(String name)
@@ -124,15 +116,10 @@
return MESSAGES.format("decorator-method-needs-delegate-parameter", asString(method));
}
- static String decoratorReturnedWrongType(Method method, String serviceId, Object returned,
- Class serviceInterface)
+ static String decoratorReturnedWrongType(Method method, String serviceId, Object returned, Class serviceInterface)
{
- return MESSAGES.format(
- "decorator-returned-wrong-type",
- asString(method),
- serviceId,
- returned,
- serviceInterface.getName());
+ return MESSAGES.format("decorator-returned-wrong-type", asString(method), serviceId, returned,
+ serviceInterface.getName());
}
static String creatingService(String serviceId)
@@ -163,10 +150,8 @@
static String contributionWrongReturnType(Method method)
{
- return MESSAGES.format(
- "contribution-wrong-return-type",
- asString(method),
- toJavaClassName(method.getReturnType()));
+ return MESSAGES.format("contribution-wrong-return-type", asString(method),
+ toJavaClassName(method.getReturnType()));
}
static String tooManyContributionParameters(Method method)
@@ -194,22 +179,18 @@
return MESSAGES.format("contribution-key-was-null", serviceId, def);
}
- static String contributionWrongValueType(String serviceId, ContributionDef def,
- Class actualClass, Class expectedClass)
+ static String contributionWrongValueType(String serviceId, ContributionDef def, Class actualClass,
+ Class expectedClass)
{
return MESSAGES.format("contribution-wrong-value-type", serviceId, def, actualClass
.getName(), expectedClass.getName());
}
- static String contributionWrongKeyType(String serviceId, ContributionDef def,
- Class actualClass, Class expectedClass)
+ static String contributionWrongKeyType(String serviceId, ContributionDef def, Class actualClass,
+ Class expectedClass)
{
- return MESSAGES.format(
- "contribution-wrong-key-type",
- serviceId,
- def,
- actualClass.getName(),
- expectedClass.getName());
+ return MESSAGES.format("contribution-wrong-key-type", serviceId, def, actualClass.getName(),
+ expectedClass.getName());
}
static String tooManyConfigurationParameters(String methodId)
@@ -225,11 +206,7 @@
static String contributionDuplicateKey(String serviceId, ContributionDef contributionDef,
ContributionDef existingDef)
{
- return MESSAGES.format(
- "contribution-duplicate-key",
- serviceId,
- contributionDef,
- existingDef);
+ return MESSAGES.format("contribution-duplicate-key", serviceId, contributionDef, existingDef);
}
static String errorBuildingService(String serviceId, ServiceDef serviceDef, Throwable cause)
@@ -244,10 +221,7 @@
static String tooManyPublicConstructors(Class moduleBuilderClass, Constructor constructor)
{
- return MESSAGES.format(
- "too-many-public-constructors",
- moduleBuilderClass.getName(),
- constructor);
+ return MESSAGES.format("too-many-public-constructors", moduleBuilderClass.getName(), constructor);
}
static String recursiveModuleConstructor(Class builderClass, Constructor constructor)
@@ -311,11 +285,25 @@
.toJavaClassName(objectType), ClassFabUtils.toJavaClassName(marker));
}
- static String manyServicesMatchMarker(Class objectType, Class marker,
- Collection<ServiceDef> matchingServices)
+ static String manyServicesMatchMarker(Class objectType, Class marker, Collection<ServiceDef> matchingServices)
{
return MESSAGES.format("many-services-match-marker", ClassFabUtils
.toJavaClassName(objectType), ClassFabUtils.toJavaClassName(marker), InternalUtils
.joinSorted(matchingServices));
+ }
+
+ static String overlappingServiceProxyProviders()
+ {
+ return MESSAGES.get("overlapping-service-proxy-providers");
+ }
+
+ static String unexpectedServiceProxyProvider()
+ {
+ return MESSAGES.get("unexpected-service-proxy-provider");
+ }
+
+ static String noProxyProvider(String serviceId)
+ {
+ return MESSAGES.format("no-proxy-provider", serviceId);
}
}
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=595970&r1=595969&r2=595970&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 Sat Nov 17 08:36:50 2007
@@ -27,9 +27,12 @@
import org.apache.tapestry.ioc.services.*;
import org.slf4j.Logger;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
import static java.lang.String.format;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Modifier;
import java.util.*;
public class ModuleImpl implements Module
@@ -64,8 +67,8 @@
*/
private final Map<String, Object> _services = newCaseInsensitiveMap();
- public ModuleImpl(InternalRegistry registry, ServiceActivityTracker tracker,
- ModuleDef moduleDef, ClassFactory classFactory, Logger logger)
+ public ModuleImpl(InternalRegistry registry, ServiceActivityTracker tracker, ModuleDef moduleDef,
+ ClassFactory classFactory, Logger logger)
{
_registry = registry;
_tracker = tracker;
@@ -199,8 +202,7 @@
try
{
- ServiceBuilderResources resources = new ServiceResourcesImpl(_registry, this, def,
- _classFactory, logger);
+ ServiceBuilderResources resources = new ServiceResourcesImpl(_registry, this, def, _classFactory, logger);
// Build up a stack of operations that will be needed to realize the service
// (by the proxy, at a later date).
@@ -215,8 +217,7 @@
if (!serviceInterface.isInterface()) return creator.createObject();
- creator = new LifecycleWrappedServiceCreator(_registry, def.getServiceScope(),
- resources, creator);
+ creator = new LifecycleWrappedServiceCreator(_registry, def.getServiceScope(), resources, creator);
// Don't allow the core IOC services services to be decorated.
@@ -227,8 +228,7 @@
creator = new RecursiveServiceCreationCheckWrapper(def, creator, logger);
- JustInTimeObjectCreator delegate = new JustInTimeObjectCreator(_tracker, creator,
- serviceId);
+ JustInTimeObjectCreator delegate = new JustInTimeObjectCreator(_tracker, creator, serviceId);
Object proxy = createProxy(resources, delegate);
@@ -271,8 +271,7 @@
Constructor[] constructors = builderClass.getConstructors();
- if (constructors.length == 0)
- throw new RuntimeException(IOCMessages.noPublicConstructors(builderClass));
+ if (constructors.length == 0) throw new RuntimeException(IOCMessages.noPublicConstructors(builderClass));
if (constructors.length > 1)
{
@@ -296,9 +295,7 @@
Constructor constructor = constructors[0];
if (_insideConstructor)
- throw new RuntimeException(IOCMessages.recursiveModuleConstructor(
- builderClass,
- constructor));
+ throw new RuntimeException(IOCMessages.recursiveModuleConstructor(builderClass, constructor));
ObjectLocator locator = new ObjectLocatorImpl(_registry, this);
Map<Class, Object> parameterDefaults = newMap();
@@ -312,11 +309,9 @@
{
_insideConstructor = true;
- Object[] parameterValues = InternalUtils.calculateParameters(
- locator,
- parameterDefaults,
- constructor.getParameterTypes(),
- constructor.getParameterAnnotations());
+ Object[] parameterValues = InternalUtils.calculateParameters(locator, parameterDefaults,
+ constructor.getParameterTypes(),
+ constructor.getParameterAnnotations());
return constructor.newInstance(parameterValues);
}
@@ -346,12 +341,52 @@
return createProxyInstance(creator, serviceId, serviceInterface, toString);
}
- private Object createProxyInstance(ObjectCreator creator, String serviceId,
- Class serviceInterface, String description)
+ private Object createProxyInstance(ObjectCreator creator, String serviceId, Class serviceInterface,
+ String description)
{
- ClassFab cf = _registry.newClass(serviceInterface);
+ ServiceProxyToken token = SerializationSupport.createToken(serviceId);
- return ClassFabUtils.createObjectCreatorProxy(cf, serviceInterface, creator, description);
+ ClassFab classFab = _registry.newClass(serviceInterface);
+
+ 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,
+ "{ _creator = $1; _token = $2; }");
+
+ // Make proxies serializable by writing the token to the stream.
+
+ classFab.addInterface(Serializable.class);
+
+ // 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});
+
+ classFab.addMethod(Modifier.PRIVATE, writeReplaceSig, "return _token;");
+
+ // Now delegate all the methods.
+
+ String body = format("return (%s) _creator.createObject();", serviceInterface.getName());
+
+ MethodSignature sig = new MethodSignature(serviceInterface, "_delegate", null, null);
+
+ classFab.addMethod(Modifier.PRIVATE, sig, body);
+
+ classFab.proxyMethodsToDelegate(serviceInterface, "_delegate()", description);
+
+ Class proxyClass = classFab.createClass();
+
+ try
+ {
+ return proxyClass.getConstructors()[0].newInstance(creator, token);
+ }
+ catch (Exception ex)
+ {
+ // Exceptions should not happen.
+
+ throw new RuntimeException(ex.getMessage(), ex);
+ }
}
public Set<ContributionDef> getContributorDefsForService(String serviceId)
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=595970&r1=595969&r2=595970&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 Sat Nov 17 08:36:50 2007
@@ -35,7 +35,7 @@
import java.lang.reflect.InvocationTargetException;
import java.util.*;
-public class RegistryImpl implements Registry, InternalRegistry
+public class RegistryImpl implements Registry, InternalRegistry, ServiceProxyProvider
{
private static final String SYMBOL_SOURCE_SERVICE_ID = "SymbolSource";
@@ -97,8 +97,8 @@
*/
private final Map<Class, List<ServiceDef>> _markerToServiceDef = newMap();
- public static final class OrderedConfigurationToOrdererAdaptor<T> implements
- OrderedConfiguration<T>
+
+ public static final class OrderedConfigurationToOrdererAdaptor<T> implements OrderedConfiguration<T>
{
private final Orderer<T> _orderer;
@@ -120,8 +120,7 @@
* @param classFactory TODO
* @param loggerSource used to obtain Logger instances
*/
- public RegistryImpl(Collection<ModuleDef> moduleDefs, ClassFactory classFactory,
- LoggerSource loggerSource)
+ public RegistryImpl(Collection<ModuleDef> moduleDefs, ClassFactory classFactory, LoggerSource loggerSource)
{
_loggerSource = loggerSource;
@@ -129,10 +128,7 @@
_tracker = scoreboardAndTracker;
- addBuiltin(
- SERVICE_ACTIVITY_SCOREBOARD_SERVICE_ID,
- ServiceActivityScoreboard.class,
- scoreboardAndTracker);
+ addBuiltin(SERVICE_ACTIVITY_SCOREBOARD_SERVICE_ID, ServiceActivityScoreboard.class, scoreboardAndTracker);
addBuiltin(LOG_SOURCE_SERVICE_ID, LoggerSource.class, _loggerSource);
@@ -150,10 +146,7 @@
_registryShutdownHub = new RegistryShutdownHubImpl(logger);
- addBuiltin(
- REGISTRY_SHUTDOWN_HUB_SERVICE_ID,
- RegistryShutdownHub.class,
- _registryShutdownHub);
+ addBuiltin(REGISTRY_SHUTDOWN_HUB_SERVICE_ID, RegistryShutdownHub.class, _registryShutdownHub);
_lifecycles.put("singleton", new SingletonServiceLifecycle());
@@ -179,9 +172,8 @@
Module existing = _serviceIdToModule.get(serviceId);
- if (existing != null)
- throw new RuntimeException(IOCMessages.serviceIdConflict(serviceId, existing
- .getServiceDef(serviceId), serviceDef));
+ if (existing != null) throw new RuntimeException(IOCMessages.serviceIdConflict(serviceId, existing
+ .getServiceDef(serviceId), serviceDef));
_serviceIdToModule.put(serviceId, module);
@@ -195,6 +187,8 @@
}
scoreboardAndTracker.startup();
+
+ SerializationSupport.setProvider(this);
}
/**
@@ -281,11 +275,10 @@
_lock.lock();
_registryShutdownHub.fireRegistryDidShutdown();
+
+ SerializationSupport.clearProvider(this);
}
- /**
- * Internal access, usually from another module.
- */
public <T> T getService(String serviceId, Class<T> serviceInterface)
{
_lock.check();
@@ -329,9 +322,8 @@
{
Module module = _serviceIdToModule.get(serviceId);
- if (module == null)
- throw new RuntimeException(IOCMessages.noSuchService(serviceId, _serviceIdToModule
- .keySet()));
+ if (module == null) throw new RuntimeException(IOCMessages.noSuchService(serviceId, _serviceIdToModule
+ .keySet()));
return module;
}
@@ -382,8 +374,7 @@
{
ObjectProvider contribution = new ObjectProvider()
{
- public <T> T provide(Class<T> objectType, AnnotationProvider annotationProvider,
- ObjectLocator locator)
+ public <T> T provide(Class<T> objectType, AnnotationProvider annotationProvider, ObjectLocator locator)
{
return findServiceByMarkerAndType(objectType, annotationProvider);
}
@@ -395,8 +386,7 @@
return orderer.getOrdered();
}
- public <K, V> Map<K, V> getMappedConfiguration(ServiceDef serviceDef, Class<K> keyType,
- Class<V> objectType)
+ public <K, V> Map<K, V> getMappedConfiguration(ServiceDef serviceDef, Class<K> keyType, Class<V> objectType)
{
_lock.check();
@@ -416,13 +406,7 @@
Collection<Module> modules = _modules;
for (Module m : modules)
- addToMappedConfiguration(
- configuration,
- keyToContribution,
- keyType,
- objectType,
- serviceDef,
- m);
+ addToMappedConfiguration(configuration, keyToContribution, keyType, objectType, serviceDef, m);
return result;
}
@@ -442,8 +426,7 @@
private <K, V> void addToMappedConfiguration(MappedConfiguration<K, V> configuration,
Map<K, ContributionDef> keyToContribution, Class<K> keyClass,
- Class<V> valueType,
- ServiceDef serviceDef, Module module)
+ Class<V> valueType, ServiceDef serviceDef, Module module)
{
String serviceId = serviceDef.getServiceId();
Set<ContributionDef> contributions = module.getContributorDefsForService(serviceId);
@@ -454,13 +437,15 @@
boolean debug = logger.isDebugEnabled();
- ObjectLocator locator = new ServiceResourcesImpl(this, module, serviceDef, _classFactory,
- logger);
+ ObjectLocator locator = new ServiceResourcesImpl(this, module, serviceDef, _classFactory, logger);
for (ContributionDef def : contributions)
{
- MappedConfiguration<K, V> validating = new ValidatingMappedConfigurationWrapper<K, V>(
- serviceId, def, logger, keyClass, valueType, keyToContribution, configuration);
+ MappedConfiguration<K, V> validating = new ValidatingMappedConfigurationWrapper<K, V>(serviceId, def,
+ logger, keyClass,
+ valueType,
+ keyToContribution,
+ configuration);
if (debug) logger.debug(IOCMessages.invokingMethod(def));
@@ -469,8 +454,8 @@
}
- private <T> void addToUnorderedConfiguration(Configuration<T> configuration,
- Class<T> valueType, ServiceDef serviceDef, Module module)
+ private <T> void addToUnorderedConfiguration(Configuration<T> configuration, Class<T> valueType,
+ ServiceDef serviceDef, Module module)
{
String serviceId = serviceDef.getServiceId();
Set<ContributionDef> contributions = module.getContributorDefsForService(serviceId);
@@ -481,13 +466,12 @@
boolean debug = logger.isDebugEnabled();
- ObjectLocator locator = new ServiceResourcesImpl(this, module, serviceDef, _classFactory,
- logger);
+ ObjectLocator locator = new ServiceResourcesImpl(this, module, serviceDef, _classFactory, logger);
for (ContributionDef def : contributions)
{
- Configuration<T> validating = new ValidatingConfigurationWrapper<T>(serviceId, logger,
- valueType, def, configuration);
+ Configuration<T> validating = new ValidatingConfigurationWrapper<T>(serviceId, logger, valueType, def,
+ configuration);
if (debug) logger.debug(IOCMessages.invokingMethod(def));
@@ -495,8 +479,8 @@
}
}
- private <T> void addToOrderedConfiguration(OrderedConfiguration<T> configuration,
- Class<T> valueType, ServiceDef serviceDef, Module module)
+ private <T> void addToOrderedConfiguration(OrderedConfiguration<T> configuration, Class<T> valueType,
+ ServiceDef serviceDef, Module module)
{
String serviceId = serviceDef.getServiceId();
Set<ContributionDef> contributions = module.getContributorDefsForService(serviceId);
@@ -506,13 +490,12 @@
Logger logger = getServiceLogger(serviceId);
boolean debug = logger.isDebugEnabled();
- ObjectLocator locator = new ServiceResourcesImpl(this, module, serviceDef, _classFactory,
- logger);
+ ObjectLocator locator = new ServiceResourcesImpl(this, module, serviceDef, _classFactory, logger);
for (ContributionDef def : contributions)
{
- OrderedConfiguration<T> validating = new ValidatingOrderedConfigurationWrapper<T>(
- serviceId, def, logger, valueType, configuration);
+ OrderedConfiguration<T> validating = new ValidatingOrderedConfigurationWrapper<T>(serviceId, def, logger,
+ valueType, configuration);
if (debug) logger.debug(IOCMessages.invokingMethod(def));
@@ -544,9 +527,7 @@
Collections.sort(serviceIds);
- throw new RuntimeException(IOCMessages.manyServiceMatches(
- serviceInterface,
- serviceIds));
+ throw new RuntimeException(IOCMessages.manyServiceMatches(serviceInterface, serviceIds));
}
}
@@ -575,9 +556,7 @@
if (result == null)
{
- ServiceLifecycleSource source = getService(
- "ServiceLifecycleSource",
- ServiceLifecycleSource.class);
+ ServiceLifecycleSource source = getService("ServiceLifecycleSource", ServiceLifecycleSource.class);
result = source.get(scope);
}
@@ -602,8 +581,7 @@
if (decorators.isEmpty()) continue;
- ServiceResources resources = new ServiceResourcesImpl(this, module, serviceDef,
- _classFactory, logger);
+ ServiceResources resources = new ServiceResourcesImpl(this, module, serviceDef, _classFactory, logger);
for (DecoratorDef dd : decorators)
{
@@ -623,13 +601,11 @@
return _classFactory.newClass(serviceInterface);
}
- private <T> T getObject(Class<T> objectType, AnnotationProvider annotationProvider,
- ObjectLocator locator)
+ private <T> T getObject(Class<T> objectType, AnnotationProvider annotationProvider, ObjectLocator locator)
{
_lock.check();
- AnnotationProvider effectiveProvider = annotationProvider != null ? annotationProvider
- : new NullAnnotationProvider();
+ AnnotationProvider effectiveProvider = annotationProvider != null ? annotationProvider : new NullAnnotationProvider();
// We do a check here for known marker/type combinations, so that you can use a marker
// annotation
@@ -640,9 +616,8 @@
if (result != null) return result;
- MasterObjectProvider masterProvider = getService(
- IOCConstants.MASTER_OBJECT_PROVIDER_SERVICE_ID,
- MasterObjectProvider.class);
+ MasterObjectProvider masterProvider = getService(IOCConstants.MASTER_OBJECT_PROVIDER_SERVICE_ID,
+ MasterObjectProvider.class);
return masterProvider.provide(objectType, effectiveProvider, locator, true);
}
@@ -686,10 +661,7 @@
.noServicesMatchMarker(objectType, marker));
default:
- throw new RuntimeException(IOCMessages.manyServicesMatchMarker(
- objectType,
- marker,
- matches));
+ throw new RuntimeException(IOCMessages.manyServicesMatchMarker(objectType, marker, matches));
}
}
@@ -727,8 +699,7 @@
*/
private synchronized SymbolSource getSymbolSource()
{
- if (_symbolSource == null)
- _symbolSource = getService(SYMBOL_SOURCE_SERVICE_ID, SymbolSource.class);
+ if (_symbolSource == null) _symbolSource = getService(SYMBOL_SOURCE_SERVICE_ID, SymbolSource.class);
return _symbolSource;
}
@@ -739,8 +710,7 @@
Constructor constructor = InternalUtils.findAutobuildConstructor(clazz);
- if (constructor == null)
- throw new RuntimeException(IOCMessages.noAutobuildConstructor(clazz));
+ if (constructor == null) throw new RuntimeException(IOCMessages.noAutobuildConstructor(clazz));
Throwable failure = null;
// An empty map, because when performing autobuilding outside the context of building a
@@ -750,10 +720,7 @@
try
{
- Object[] parameters = InternalUtils.calculateParametersForConstructor(
- constructor,
- this,
- empty);
+ Object[] parameters = InternalUtils.calculateParametersForConstructor(constructor, this, empty);
return clazz.cast(constructor.newInstance(parameters));
}
@@ -768,8 +735,7 @@
String description = _classFactory.getConstructorLocation(constructor).toString();
- throw new RuntimeException(IOCMessages.autobuildConstructorError(description, failure),
- failure);
+ throw new RuntimeException(IOCMessages.autobuildConstructorError(description, failure), failure);
}
public <T> T proxy(Class<T> interfaceClass, final Class<? extends T> implementationClass)
@@ -806,5 +772,10 @@
.getName(), interfaceClass.getName());
return ClassFabUtils.createObjectCreatorProxy(cf, interfaceClass, justInTime, description);
+ }
+
+ public Object provideServiceProxy(String serviceId)
+ {
+ return getService(serviceId, Object.class);
}
}
Added: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/SerializationSupport.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/SerializationSupport.java?rev=595970&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/SerializationSupport.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/SerializationSupport.java Sat Nov 17 08:36:50 2007
@@ -0,0 +1,67 @@
+package org.apache.tapestry.ioc.internal;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.ref.WeakReference;
+
+/**
+ * Serialization support for service proxies.
+ */
+class SerializationSupport
+{
+ private static final Logger LOGGER = LoggerFactory.getLogger(SerializationSupport.class);
+
+ // We use a weak reference so that the underlying Registry can be reclaimed by the garbage collector
+ // even if it is not explicitly shut down.
+
+ private static WeakReference<ServiceProxyProvider> _providerRef;
+
+ static synchronized void setProvider(ServiceProxyProvider proxyProvider)
+ {
+ ServiceProxyProvider existing = currentProvider();
+
+ if (existing != null) LOGGER.error(IOCMessages.overlappingServiceProxyProviders());
+
+ _providerRef = new WeakReference<ServiceProxyProvider>(proxyProvider);
+ }
+
+ private static ServiceProxyProvider currentProvider()
+ {
+ return _providerRef == null ? null : _providerRef.get();
+ }
+
+ static synchronized void clearProvider(ServiceProxyProvider proxyProvider)
+ {
+ ServiceProxyProvider existing = currentProvider();
+
+ // The registry does a setProvider() at startup, and we want to make sure that we're the only Registry, that
+ // there hasn't been another setProvider() by another Registry.
+
+ if (existing != proxyProvider)
+ {
+ LOGGER.error(IOCMessages.unexpectedServiceProxyProvider());
+ return;
+ }
+
+ // Good. It's all the expected simple case, without duelling registries. Kill the reference
+ // to the registry.
+
+ _providerRef = null;
+ }
+
+ static synchronized Object readResolve(String serviceId)
+ {
+ ServiceProxyProvider provider = currentProvider();
+
+ if (provider == null) throw new RuntimeException(IOCMessages.noProxyProvider(serviceId));
+
+ return provider.provideServiceProxy(serviceId);
+ }
+
+ static ServiceProxyToken createToken(String serviceId)
+ {
+ return new ServiceProxyToken(serviceId);
+ }
+
+}
\ No newline at end of file
Added: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceProxyProvider.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceProxyProvider.java?rev=595970&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceProxyProvider.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceProxyProvider.java Sat Nov 17 08:36:50 2007
@@ -0,0 +1,17 @@
+package org.apache.tapestry.ioc.internal;
+
+/**
+ * Used in concert with {@link org.apache.tapestry.ioc.internal.SerializationSupport} to
+ * convert service tokens back into service proxies.
+ */
+public interface ServiceProxyProvider
+{
+ /**
+ * Look up the service and return it's proxy.
+ *
+ * @param serviceId the id of the service to obtain
+ * @return the service proxy
+ * @throws RuntimeException if the service does not exist or does not have a proxy
+ */
+ Object provideServiceProxy(String serviceId);
+}
Added: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceProxyToken.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceProxyToken.java?rev=595970&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceProxyToken.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/internal/ServiceProxyToken.java Sat Nov 17 08:36:50 2007
@@ -0,0 +1,34 @@
+package org.apache.tapestry.ioc.internal;
+
+import java.io.InvalidObjectException;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+
+/**
+ * Token that replaces a service proxy when the proxy is serialized.
+ */
+class ServiceProxyToken implements Serializable
+{
+ private final String _serviceId;
+
+ ServiceProxyToken(String serviceId)
+ {
+ _serviceId = serviceId;
+ }
+
+ Object readResolve() throws ObjectStreamException
+ {
+ try
+ {
+ return SerializationSupport.readResolve(_serviceId);
+ }
+ catch (Exception ex)
+ {
+ ObjectStreamException ose = new InvalidObjectException(ex.getMessage());
+ ose.initCause(ex);
+
+ throw ose;
+ }
+ }
+
+}
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/test/IOCTestCase.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/test/IOCTestCase.java?rev=595970&r1=595969&r2=595970&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/test/IOCTestCase.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry/ioc/test/IOCTestCase.java Sat Nov 17 08:36:50 2007
@@ -36,6 +36,10 @@
*/
public class IOCTestCase extends TestBase
{
+
+ /**
+ * Builds a Registry for the provided modules; caller should shutdown the Registry when done.
+ */
protected final Registry buildRegistry(Class... moduleClasses)
{
RegistryBuilder builder = new RegistryBuilder();
@@ -52,10 +56,8 @@
if (method.getName().equals(methodName)) return method;
}
- throw new IllegalArgumentException(String.format(
- "Class %s does not provide a method named '%s'.",
- clazz.getName(),
- methodName));
+ throw new IllegalArgumentException(
+ String.format("Class %s does not provide a method named '%s'.", clazz.getName(), methodName));
}
protected final Method findMethod(Object subject, String methodName)
@@ -210,8 +212,7 @@
expect(messages.contains(isA(String.class))).andStubReturn(contained);
}
- protected <S, T> void train_coerce(TypeCoercer coercer, S input, Class<T> expectedType,
- T coercedValue)
+ protected <S, T> void train_coerce(TypeCoercer coercer, S input, Class<T> expectedType, T coercedValue)
{
expect(coercer.coerce(input, expectedType)).andReturn(coercedValue);
}
@@ -221,8 +222,7 @@
expect(messages.contains(key)).andReturn(result).atLeastOnce();
}
- protected final void train_createInterceptor(ServiceDecorator decorator, Object coreObject,
- Object interceptor)
+ protected final void train_createInterceptor(ServiceDecorator decorator, Object coreObject, Object interceptor)
{
expect(decorator.createInterceptor(coreObject)).andReturn(interceptor);
}
@@ -276,8 +276,7 @@
expect(source.getLogger(serviceId)).andReturn(logger).atLeastOnce();
}
- protected final void train_getMessageFormatter(Messages messages, String key,
- MessageFormatter formatter)
+ protected final void train_getMessageFormatter(Messages messages, String key, MessageFormatter formatter)
{
expect(messages.getFormatter(key)).andReturn(formatter).atLeastOnce();
}
@@ -287,14 +286,13 @@
expect(r.getPath()).andReturn(path).atLeastOnce();
}
- protected final <T> void train_getService(ObjectLocator locator, Class<T> serviceInterface,
- T service)
+ protected final <T> void train_getService(ObjectLocator locator, Class<T> serviceInterface, T service)
{
expect(locator.getService(serviceInterface)).andReturn(service);
}
- protected final <T> void train_getService(ObjectLocator locator, String serviceId,
- Class<T> serviceInterface, T service)
+ protected final <T> void train_getService(ObjectLocator locator, String serviceId, Class<T> serviceInterface,
+ T service)
{
expect(locator.getService(serviceId, serviceInterface)).andReturn(service);
}
@@ -315,8 +313,7 @@
expect(def.getServiceInterface()).andReturn(serviceInterface).atLeastOnce();
}
- protected final void train_getServiceInterface(ServiceResources resources,
- Class serviceInterface)
+ protected final void train_getServiceInterface(ServiceResources resources, Class serviceInterface)
{
expect(resources.getServiceInterface()).andReturn(serviceInterface).atLeastOnce();
}
@@ -337,8 +334,7 @@
expect(log.isTraceEnabled()).andReturn(traceEnabled);
}
- protected final void train_matches(DecoratorDef decoratorDef, ServiceDef serviceDef,
- boolean matches)
+ protected final void train_matches(DecoratorDef decoratorDef, ServiceDef serviceDef, boolean matches)
{
expect(decoratorDef.matches(serviceDef)).andReturn(matches);
}
@@ -354,8 +350,8 @@
expect(resource.toURL()).andReturn(url).atLeastOnce();
}
- protected final <T extends Annotation> void train_getAnnotation(
- AnnotationProvider annotationProvider, Class<T> annotationClass, T annotation)
+ protected final <T extends Annotation> void train_getAnnotation(AnnotationProvider annotationProvider,
+ Class<T> annotationClass, T annotation)
{
expect(annotationProvider.getAnnotation(annotationClass)).andReturn(annotation);
}
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/resources/org/apache/tapestry/ioc/internal/IOCStrings.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/resources/org/apache/tapestry/ioc/internal/IOCStrings.properties?rev=595970&r1=595969&r2=595970&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/resources/org/apache/tapestry/ioc/internal/IOCStrings.properties (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/resources/org/apache/tapestry/ioc/internal/IOCStrings.properties Sat Nov 17 08:36:50 2007
@@ -12,68 +12,68 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-build-method-conflict=Service building method %s conflicts with (has the same name as, but different parameters than) \
- previously seen method %s and has been ignored.
-build-method-wrong-return-type=Method %s is named like a service builder method, \
- but the return type (%s) is not acceptable (try an interface). \
- The method has been ignored.
-decorator-method-wrong-return-type=Method %s is named like a service decorator method, \
- but the return type (%s) is not acceptable (try Object). The method has been ignored.
-builder-locked=The Registry Builder has created the Registry, further operations are not allowed.
-service-wrong-interface=Service '%s' implements interface %s, which is not compatible with the requested type %s.
-instantiate-builder-error=Unable to instantiate class %s as a module builder: %s
+build-method-conflict=Service building method %s conflicts with (has the same name as, but different parameters than) \
+ previously seen method %s and has been ignored.
+build-method-wrong-return-type=Method %s is named like a service builder method, \
+ but the return type (%s) is not acceptable (try an interface). \
+ The method has been ignored.
+decorator-method-wrong-return-type=Method %s is named like a service decorator method, \
+ but the return type (%s) is not acceptable (try Object). The method has been ignored.
+builder-locked=The Registry Builder has created the Registry, further operations are not allowed.
+service-wrong-interface=Service '%s' implements interface %s, which is not compatible with the requested type %s.
+instantiate-builder-error=Unable to instantiate class %s as a module builder: %s
builder-method-error=Error invoking service builder method %s (for service '%s'): %s
-constructor-error=Error invoking constructor %s (for service '%s'): %s
-decorator-method-error=Error invoking service decorator method %s (for service '%s'): %s
-builder-method-returned-null=Builder method %s (for service '%s') returned null.
-no-service-matches-type=No service implements the interface %s.
-many-service-matches=Service interface %s is matched by %d services: %s. \
+constructor-error=Error invoking constructor %s (for service '%s'): %s
+decorator-method-error=Error invoking service decorator method %s (for service '%s'): %s
+builder-method-returned-null=Builder method %s (for service '%s') returned null.
+no-service-matches-type=No service implements the interface %s.
+many-service-matches=Service interface %s is matched by %d services: %s. \
Automatic dependency resolution requires that exactly one service implement the interface.
no-services-match-marker=Unable to locate any service assignable to type %s with marker annotation %s.
many-services-match-marker=Unable to locate a single service assignable to type %s with marker annotation %s. \
- All of the following services match: %s.
-unknown-scope=Unknown service scope '%s'.
-decorator-method-needs-delegate-parameter=Decorator methods must a parameter for the service delegate \
- (i.e., the object the created interceptor will delegate to). \
- Method %s does not include such a parameter, and has been ignored.
-decorator-returned-wrong-type=Decorator method %s (invoked for service '%s') returned %s, \
- which is not assignable to the %s service interface.
-creating-service=Creating service '%s'.
+ All of the following services match: %s.
+unknown-scope=Unknown service scope '%s'.
+decorator-method-needs-delegate-parameter=Decorator methods must a parameter for the service delegate \
+ (i.e., the object the created interceptor will delegate to). \
+ Method %s does not include such a parameter, and has been ignored.
+decorator-returned-wrong-type=Decorator method %s (invoked for service '%s') returned %s, \
+ which is not assignable to the %s service interface.
+creating-service=Creating service '%s'.
invoking-method=Invoking method %s.
-invoking-constructor=Invoking constructor %s.
-recursive-service-build=Construction of service '%s' has failed due to recursion: \
- the service depends on itself in some way. \
- Please check %s for references to another service that is itself dependent on service '%1$s'.
-contribution-wrong-return-type=Method %s is named like a service contributor method, \
- but the return type (%s) is not appropriate (try void). The return value will be ignored.
-too-many-contribution-parameters=Service contribution method %s contains more than one parameter of type Configuration, \
- OrderedConfiguration, or MappedConfiguration. Exactly one such parameter is required for a service contribution method. \
- The method has been ignored.
-too-many-configuration-parameters=Service builder method %s contains more than one parameter of type \
- Collection, List, or Map. Parameters of this type are the way in which service configuration values, \
- collected from service contributor methods, are provided to the service builder. \
- Services are only allowed a single configuration. Unexpected results or failures may occur.
-no-contribution-parameter=Service contribution method %s does not contain a parameter of type \
- Configuration, OrderedConfiguration or MappedConfiguration. This parameter is how the method \
- make contributions into the service's configuration. The method has been ignored.
-contribution-method-error=Error invoking service contribution method %s: %s
-contribution-was-null=Service contribution (to service '%s', by %s) was null and has been ignored.
-contribution-key-was-null=Key for service contribution (to service '%s', by %s) was null and has been ignored.
-contribution-wrong-value-type=Service contribution (to service '%s', by %s) was an instance of %s, \
- but %s was expected. The contribution has been ignored.
-contribution-wrong-key-type=Key for service contribution (to service '%s', by %s) was an instance of %s, \
- but %s was expected. The contribution has been ignored.
-contribution-duplicate-key=Service contribution (to service '%s', by %s) conflicts with \
- existing contribution (by %s) and has been ignored.
-generic-type-not-supported=Generic type '%s' is not supported. Only simple parameterized lists are \
- supported.
-error-building-service=Error building service proxy for service '%s' (at %s): %s
-no-public-constructors=Module builder class %s does not contain any public constructors.
-too-many-public-constructors=Module bulider class %s contains more than one public constructor. \
- The first constructor, %s, is being used. \
- You should change the class to have only a single public constructor.
-recursive-module-constructor=The constructor for module class %s is recursive: it depends on itself in some way. \
- The constructor, %s, is in some way is triggering a service builder, decorator or contribution method within the class.
+invoking-constructor=Invoking constructor %s.
+recursive-service-build=Construction of service '%s' has failed due to recursion: \
+ the service depends on itself in some way. \
+ Please check %s for references to another service that is itself dependent on service '%1$s'.
+contribution-wrong-return-type=Method %s is named like a service contributor method, \
+ but the return type (%s) is not appropriate (try void). The return value will be ignored.
+too-many-contribution-parameters=Service contribution method %s contains more than one parameter of type Configuration, \
+ OrderedConfiguration, or MappedConfiguration. Exactly one such parameter is required for a service contribution method. \
+ The method has been ignored.
+too-many-configuration-parameters=Service builder method %s contains more than one parameter of type \
+ Collection, List, or Map. Parameters of this type are the way in which service configuration values, \
+ collected from service contributor methods, are provided to the service builder. \
+ Services are only allowed a single configuration. Unexpected results or failures may occur.
+no-contribution-parameter=Service contribution method %s does not contain a parameter of type \
+ Configuration, OrderedConfiguration or MappedConfiguration. This parameter is how the method \
+ make contributions into the service's configuration. The method has been ignored.
+contribution-method-error=Error invoking service contribution method %s: %s
+contribution-was-null=Service contribution (to service '%s', by %s) was null and has been ignored.
+contribution-key-was-null=Key for service contribution (to service '%s', by %s) was null and has been ignored.
+contribution-wrong-value-type=Service contribution (to service '%s', by %s) was an instance of %s, \
+ but %s was expected. The contribution has been ignored.
+contribution-wrong-key-type=Key for service contribution (to service '%s', by %s) was an instance of %s, \
+ but %s was expected. The contribution has been ignored.
+contribution-duplicate-key=Service contribution (to service '%s', by %s) conflicts with \
+ existing contribution (by %s) and has been ignored.
+generic-type-not-supported=Generic type '%s' is not supported. Only simple parameterized lists are \
+ supported.
+error-building-service=Error building service proxy for service '%s' (at %s): %s
+no-public-constructors=Module builder class %s does not contain any public constructors.
+too-many-public-constructors=Module bulider class %s contains more than one public constructor. \
+ The first constructor, %s, is being used. \
+ You should change the class to have only a single public constructor.
+recursive-module-constructor=The constructor for module class %s is recursive: it depends on itself in some way. \
+ The constructor, %s, is in some way is triggering a service builder, decorator or contribution method within the class.
constructed-configuration=Constructed configuration: %s
service-construction-failed=Construction of service %s failed: %s
no-such-service=Service id '%s' is not defined by any module. Defined services: %s.
@@ -84,4 +84,6 @@
error-in-bind-method=Error invoking service binder method %s: %s
no-autobuild-constructor=Class %s does not contain a public constructor needed to autobuild.
autobuild-constructor-error=Error invoking constructor %s: %s
-
\ No newline at end of file
+overlapping-service-proxy-providers=Setting a new service proxy provider when there's already an existing provider. This may indicate that you have multiple IoC Registries.
+unexpected-service-proxy-provider=Unexpected service proxy provider when clearing the provider. This may indicate that you have multiple IoC Registries.
+no-proxy-provider=Service token for service '%s' can not be converted back into a proxy because no proxy provider has been registered. This may indicate that an IoC Registry has not been started yet.
\ No newline at end of file
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/resources/org/apache/tapestry/ioc/internal/services/ServiceStrings.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/resources/org/apache/tapestry/ioc/internal/services/ServiceStrings.properties?rev=595970&r1=595969&r2=595970&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/resources/org/apache/tapestry/ioc/internal/services/ServiceStrings.properties (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/resources/org/apache/tapestry/ioc/internal/services/ServiceStrings.properties Sat Nov 17 08:36:50 2007
@@ -12,31 +12,31 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-unable-to-add-method=Unable to add method %s to class %s: %s
-unable-to-add-field=Unable to add field %s to class %s: %s
-unable-to-add-constructor=Unable to add constructor to class %s: %s
-unable-to-create-class=Unable to create class %s as subclass of %s: %s
-unable-to-lookup-class=Unable to lookup class %s: %s
-unable-to-write-class=Unable to create class %s: %s
-duplicate-method-in-class=Attempt to redefine method %s of class %s.
-logging-interceptor=<Logging interceptor for %s(%s)>
-thread-cleanup-error=Error invoking listener %s: %s
-no-such-property=Class %s does not contain a property named '%s'.
-read-not-supported=Class %s does not provide an accessor ('getter') method for property '%s'.
-write-not-supported=Class %s does not provide an mutator ('setter') method for property '%s'.
-read-failure=Error reading property '%s' of %s: %s
-write-failure=Error updating property '%s' of %s: %s
-property-type-mismatch=Property '%s' of class %s is of type %s, which is not assignable to type %s.
-extra-filter-method=Method %s of filter interface %s does not have a matching method in %s.
-unmatched-service-method=Method %s has no match in filter interface %s.
-unknown-object-provider=Object provider '%s' does not exist (in object reference '%s').
-shutdown-listener-error=Error notifying %s of registry shutdown: %s
+unable-to-add-method=Unable to add method %s to class %s: %s
+unable-to-add-field=Unable to add field %s to class %s: %s
+unable-to-add-constructor=Unable to add constructor to class %s: %s
+unable-to-create-class=Unable to create class %s as subclass of %s: %s
+unable-to-lookup-class=Unable to lookup class %s: %s
+unable-to-write-class=Unable to create class %s: %s
+duplicate-method-in-class=Attempt to redefine method %s of class %s.
+logging-interceptor=<Logging interceptor for %s(%s)>
+thread-cleanup-error=Error invoking listener %s: %s
+no-such-property=Class %s does not contain a property named '%s'.
+read-not-supported=Class %s does not provide an accessor ('getter') method for property '%s'.
+write-not-supported=Class %s does not provide an mutator ('setter') method for property '%s'.
+read-failure=Error reading property '%s' of %s: %s
+write-failure=Error updating property '%s' of %s: %s
+property-type-mismatch=Property '%s' of class %s is of type %s, which is not assignable to type %s.
+extra-filter-method=Method %s of filter interface %s does not have a matching method in %s.
+unmatched-service-method=Method %s has no match in filter interface %s.
+unknown-object-proxyProvider=Object proxyProvider '%s' does not exist (in object reference '%s').
+shutdown-listener-error=Error notifying %s of registry shutdown: %s
no-coercion-found=Could not find a coercion from type %s to type %s. Available coercions: %s.
recursive-symbol=Symbol '%s' is defined in terms of itself (%s).
symbol-undefined=Symbol '%s' is not defined.
symbol-undefined-in-path=Symbol '%s' is not defined (in %s).
missing-symbol-close-brace=Input string '%s' is missing a symbol closing brace.
missing-symbol-close-brace-in-path=Input string '%s' is missing a symbol closing brace (in %s).
-failed-coercion=Coercion of %s to type %s (via %s) failed: %s
+failed-coercion=Coercion of %s to type %s (via %s) failed: %s
registry-shutdown=Proxy for service %s is no longer active because the IOC Registry has been shut down.
service-build-failure=Exception constructing service '%s': %s
Added: tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/serialization.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/serialization.apt?rev=595970&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/serialization.apt (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/serialization.apt Sat Nov 17 08:36:50 2007
@@ -0,0 +1,51 @@
+ ----
+ Service Serialization
+ ----
+
+Service Serialization
+
+ Every once in a while you may need to serialize a service. For example, you may store an object into
+ the HttpSession that holds a reference to a service. In a clustered environment, that object will
+ be serialized and broadcast to other servers in the cluster.
+
+ Services in Tapestry are serializable. Specifically, service <proxies> are serializable.
+
+ Your service implementations <do not> have to be serializable.
+
+ Serialization works as follows:
+
+ * When a proxy is serialized, it instead serializes a <token> object.
+
+ * The token object is what's stored in the output stream.
+
+ * When the token is de-serialized, it locates the service proxy in the current Registry and returns that.
+
+ []
+
+ The end result is very efficient: just the tiny tokens are serialized, not the services with their
+ proxies, configurations, implementations, dependencies, internal state and so forth.
+
+ Again, note that the actual service implementation is not serialized. Due to Tapestry's lazy creation policy,
+ the service implementation may not even exist. Since outside code only sees the proxy, there's no
+ difference.
+
+Registry Resolution
+
+ The one trick here is locating the service proxy. Tapestry uses a <weak reference> to the Registry to do this.
+ When a Registry starts up, it is stored in the reference, so that de-serialization can work.
+
+ The reference is cleared when you shut down the Registry. If you stop using the Registry, but fail to
+ shut it down, the weak reference ensures that it will be released to the garbage collector anyway. Stil, you
+ should shutdown a Registry when done with it.
+
+ This all makes one BIG assumption: that there's just one Registry. That's normal for a web application, especially
+ when the tapestry-ioc JAR is included as part of the web application's WAR.
+
+ If you are running multiple Registries you will likely see errors in your console:
+
++---+
+[ERROR] SerializationSupport Setting a new service proxy provider when there's already an existing provider. This may indicate that you have multiple IoC Registries.
++---+
+
+
+
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/site/site.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/site/site.xml?rev=595970&r1=595969&r2=595970&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/site/site.xml (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/site/site.xml Sat Nov 17 08:36:50 2007
@@ -53,6 +53,7 @@
<item name="Decorators" href="decorator.html"/>
<item name="Configuration" href="configuration.html"/>
<item name="Type Coercion" href="coerce.html"/>
+ <item name="Serialization" href="serialization.html"/>
<item name="Case Insensitivity" href="case.html"/>
<item name="Symbols" href="symbols.html"/>
<item name="Starting the Registry" href="run.html"/>
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/IntegrationTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/IntegrationTest.java?rev=595970&r1=595969&r2=595970&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/IntegrationTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/IntegrationTest.java Sat Nov 17 08:36:50 2007
@@ -66,6 +66,8 @@
assertFalse(StaticModule.isInstantiated());
assertTrue(StaticModule.getFredRan());
+
+ r.shutdown();
}
@Test
@@ -82,6 +84,8 @@
assertFalse(StaticModule.isInstantiated());
assertTrue(StaticModule.getDecoratorRan());
+
+ r.shutdown();
}
@Test
@@ -98,6 +102,8 @@
assertEquals(names, Arrays.asList("Fred"));
assertFalse(StaticModule.isInstantiated());
+
+ r.shutdown();
}
@Test
@@ -118,9 +124,8 @@
}
catch (IllegalStateException ex)
{
- assertEquals(
- ex.getMessage(),
- "Proxy for service Fred is no longer active because the IOC Registry has been shut down.");
+ assertEquals(ex.getMessage(),
+ "Proxy for service Fred is no longer active because the IOC Registry has been shut down.");
}
// Show that toString() still works, even for a shutdown proxy.
@@ -208,6 +213,8 @@
// Random objects are size 1
assertEquals(sizer.size(this), 1);
+
+ r.shutdown();
}
@Test
@@ -225,11 +232,10 @@
}
catch (Exception ex)
{
- assertMessageContains(
- ex,
- "Exception constructing service 'UnknownScope'",
- "Unknown service scope 'magic'");
+ assertMessageContains(ex, "Exception constructing service 'UnknownScope'", "Unknown service scope 'magic'");
}
+
+ r.shutdown();
}
@Test
@@ -269,6 +275,8 @@
assertEquals(holder.getValue(), "fred");
r.cleanupThread();
+
+ r.shutdown();
}
/**
@@ -315,6 +323,8 @@
{
assertTrue(ex.getMessage().contains("has failed due to recursion"));
}
+
+ r.shutdown();
}
@Test
@@ -322,13 +332,13 @@
{
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();
assertTrue(EagerLoadModule._eagerLoadDidHappen);
+
+ r.shutdown();
}
@Test
@@ -339,6 +349,8 @@
Runnable fred = r.getService("Fred", Runnable.class);
assertSame(r.getService("FRED", Runnable.class), fred);
+
+ r.shutdown();
}
@Test
@@ -351,6 +363,8 @@
sh.setValue("Foo");
assertEquals(sh.getValue(), "Foo");
+
+ r.shutdown();
}
@Test
@@ -367,13 +381,12 @@
}
catch (RuntimeException ex)
{
- assertMessageContains(
- ex,
- "Error invoking constructor",
- "ExceptionInConstructorServiceImpl() (at ExceptionInConstructorServiceImpl.java",
- "for service 'Pingable'",
- "Yes, we have no tomatoes.");
+ assertMessageContains(ex, "Error invoking constructor",
+ "ExceptionInConstructorServiceImpl() (at ExceptionInConstructorServiceImpl.java",
+ "for service 'Pingable'", "Yes, we have no tomatoes.");
}
+
+ r.shutdown();
}
@Test
@@ -387,6 +400,8 @@
StringHolder holder = r.getService(StringHolder.class);
assertTrue(holder instanceof StringHolderImpl);
+
+ r.shutdown();
}
@Test
@@ -401,6 +416,8 @@
holder.setValue("Foo");
assertEquals(holder.getValue(), "Foo");
+
+ r.shutdown();
}
@Test
@@ -417,6 +434,8 @@
holder.setValue("Foo");
assertEquals(holder.getValue(), "Foo");
+
+ r.shutdown();
}
@Test
@@ -438,15 +457,15 @@
}
catch (RuntimeException ex)
{
- assertMessageContains(
- ex,
- "Class org.apache.tapestry.ioc.UnbuildablePingable does not contain a public constructor needed to autobuild.");
+ assertMessageContains(ex,
+ "Class org.apache.tapestry.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();
}
@Test
@@ -462,10 +481,11 @@
}
catch (RuntimeException ex)
{
- assertMessageContains(
- ex,
- "Class org.apache.tapestry.ioc.UnbuildablePingable does not contain a public constructor needed to autobuild.");
+ assertMessageContains(ex,
+ "Class org.apache.tapestry.ioc.UnbuildablePingable does not contain a public constructor needed to autobuild.");
}
+
+ r.shutdown();
}
@Test
@@ -481,15 +501,15 @@
}
catch (RuntimeException ex)
{
- assertMessageContains(
- ex,
- "Error invoking constructor org.apache.tapestry.ioc.FailInConstructorRunnable()",
- "Failure in Runnable constructor.");
+ assertMessageContains(ex, "Error invoking constructor org.apache.tapestry.ioc.FailInConstructorRunnable()",
+ "Failure in Runnable constructor.");
// Like to check that the message includes the source location
assertTrue(ex.getMessage().matches(".*\\(at FailInConstructorRunnable.java:\\d+\\).*"));
}
+
+ r.shutdown();
}
@Test
@@ -506,6 +526,8 @@
{
assertMessageContains(ex, "Service id \'PeekABoo\' is not defined by any module.");
}
+
+ r.shutdown();
}
@Test
@@ -521,10 +543,10 @@
}
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();
}
@Test
@@ -539,10 +561,11 @@
}
catch (RuntimeException ex)
{
- assertEquals(
- ex.getMessage(),
- "Service interface org.apache.tapestry.ioc.Pingable is matched by 2 services: Barney, Fred. Automatic dependency resolution requires that exactly one service implement the interface.");
+ assertEquals(ex.getMessage(),
+ "Service interface org.apache.tapestry.ioc.Pingable is matched by 2 services: Barney, Fred. Automatic dependency resolution requires that exactly one service implement the interface.");
}
+
+ r.shutdown();
}
@Test
@@ -559,6 +582,8 @@
// But the implementation is cached
assertSame(r.getService(StringHolder.class), holder);
+
+ r.shutdown();
}
@Test
@@ -570,6 +595,8 @@
assertEquals(g.getGreeting(), "Hello");
assertEquals(g.toString(), "<Proxy for Greeter(org.apache.tapestry.ioc.Greeter)>");
+
+ r.shutdown();
}
@Test
@@ -581,6 +608,8 @@
assertEquals(g.getGreeting(), "Hello");
assertEquals(g.toString(), "<Proxy for HelloGreeter(org.apache.tapestry.ioc.Greeter)>");
+
+ r.shutdown();
}
@Test
@@ -591,6 +620,8 @@
Greeter g = r.getService("InjectedBlueGreeter", Greeter.class);
assertEquals(g.getGreeting(), "Blue");
+
+ r.shutdown();
}
@Test
@@ -607,13 +638,13 @@
}
catch (RuntimeException ex)
{
- assertMessageContains(
- ex,
- "Error invoking service builder method",
- "Unable to locate a single service assignable to type org.apache.tapestry.ioc.Greeter with marker annotation org.apache.tapestry.ioc.RedMarker",
- "org.apache.tapestry.ioc.GreeterModule.buildRedGreeter1()",
- "org.apache.tapestry.ioc.GreeterModule.buildRedGreeter2()");
+ assertMessageContains(ex, "Error invoking service builder method",
+ "Unable to locate a single service assignable to type org.apache.tapestry.ioc.Greeter with marker annotation org.apache.tapestry.ioc.RedMarker",
+ "org.apache.tapestry.ioc.GreeterModule.buildRedGreeter1()",
+ "org.apache.tapestry.ioc.GreeterModule.buildRedGreeter2()");
}
+
+ r.shutdown();
}
@Test
@@ -630,12 +661,11 @@
}
catch (RuntimeException ex)
{
- assertMessageContains(
- ex,
- "Error invoking service builder method",
- " Unable to locate any service assignable to type org.apache.tapestry.ioc.Greeter with marker annotation org.apache.tapestry.ioc.YellowMarker.");
+ assertMessageContains(ex, "Error invoking service builder method",
+ " Unable to locate any service assignable to type org.apache.tapestry.ioc.Greeter with marker annotation org.apache.tapestry.ioc.YellowMarker.");
}
+ r.shutdown();
}
@SuppressWarnings("unchecked")
@@ -665,6 +695,8 @@
assertSame(tc1, tc2);
verify();
+
+ r.shutdown();
}
/**
@@ -704,6 +736,8 @@
if (serviceId.equals("BlueGreeter")) assertEquals(a.getStatus(), Status.VIRTUAL);
}
+
+ r.shutdown();
}
@Test
@@ -717,9 +751,8 @@
assertEquals(CountingGreeterImpl._instantiationCount, 0);
- assertEquals(
- g.toString(),
- "<Autobuild proxy org.apache.tapestry.ioc.CountingGreeterImpl(org.apache.tapestry.ioc.Greeter)>");
+ assertEquals(g.toString(),
+ "<Autobuild proxy org.apache.tapestry.ioc.CountingGreeterImpl(org.apache.tapestry.ioc.Greeter)>");
assertEquals(CountingGreeterImpl._instantiationCount, 0);
@@ -731,5 +764,9 @@
assertEquals(g.getGreeting(), "Hello");
assertEquals(CountingGreeterImpl._instantiationCount, 1);
}
+
+ r.shutdown();
}
+
+
}
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/RegistryBuilderTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/RegistryBuilderTest.java?rev=595970&r1=595969&r2=595970&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/RegistryBuilderTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/RegistryBuilderTest.java Sat Nov 17 08:36:50 2007
@@ -39,6 +39,8 @@
List<String> names = service.getNames();
assertEquals(names, Arrays.asList("Beta", "Gamma", "UnorderedNames"));
+
+ r.shutdown();
}
@Test
@@ -61,5 +63,7 @@
// ClassFactory service was accessed and used.
assertEquals(service.toString(), "<Proxy for Square(org.apache.tapestry.ioc.Square)>");
+
+ registry.shutdown();
}
}
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/DefaultModuleDefImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/DefaultModuleDefImplTest.java?rev=595970&r1=595969&r2=595970&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/DefaultModuleDefImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/DefaultModuleDefImplTest.java Sat Nov 17 08:36:50 2007
@@ -139,8 +139,7 @@
// BigDecimal is arbitrary, any class would do.
- ModuleDef md = new DefaultModuleDefImpl(ServiceIdConflictMethodModule.class, logger,
- _classFactory);
+ ModuleDef md = new DefaultModuleDefImpl(ServiceIdConflictMethodModule.class, logger, _classFactory);
Set<String> ids = md.getServiceIds();
@@ -204,8 +203,7 @@
invalidDecoratorMethod(VoidDecoratorMethodModule.class, "decorateVoid");
}
- private void invalidDecoratorMethod(Class moduleClass, String methodName)
- throws NoSuchMethodException
+ private void invalidDecoratorMethod(Class moduleClass, String methodName) throws NoSuchMethodException
{
Method m = moduleClass.getMethod(methodName, Object.class);
@@ -262,23 +260,17 @@
@Test
public void ordered_contribution_method()
{
- attemptConfigurationMethod(
- OrderedConfigurationModule.class,
- "Ordered",
- "contributeOrdered(OrderedConfiguration)");
+ attemptConfigurationMethod(OrderedConfigurationModule.class, "Ordered",
+ "contributeOrdered(OrderedConfiguration)");
}
@Test
public void mapped_contribution_method()
{
- attemptConfigurationMethod(
- MappedConfigurationModule.class,
- "Mapped",
- "contributeMapped(MappedConfiguration)");
+ attemptConfigurationMethod(MappedConfigurationModule.class, "Mapped", "contributeMapped(MappedConfiguration)");
}
- private void attemptConfigurationMethod(Class moduleClass, String expectedServiceId,
- String expectedMethodSignature)
+ private void attemptConfigurationMethod(Class moduleClass, String expectedServiceId, String expectedMethodSignature)
{
Logger logger = mockLogger();
@@ -387,15 +379,13 @@
try
{
- new DefaultModuleDefImpl(UninstantiableAutobuildServiceModule.class, logger,
- _classFactory);
+ new DefaultModuleDefImpl(UninstantiableAutobuildServiceModule.class, logger, _classFactory);
unreachable();
}
catch (RuntimeException ex)
{
- assertEquals(
- ex.getMessage(),
- "Class org.apache.tapestry.ioc.internal.RunnableServiceImpl (implementation of service \'Runnable\') does not contain any public constructors.");
+ assertEquals(ex.getMessage(),
+ "Class org.apache.tapestry.ioc.internal.RunnableServiceImpl (implementation of service \'Runnable\') does not contain any public constructors.");
}
verify();
@@ -406,14 +396,11 @@
{
Logger logger = mockLogger();
- logger.error(and(
- contains(NonStaticBindMethodModule.class.getName()),
- contains("but is an instance method")));
+ logger.error(and(contains(NonStaticBindMethodModule.class.getName()), contains("but is an instance method")));
replay();
- ModuleDef md = new DefaultModuleDefImpl(NonStaticBindMethodModule.class, logger,
- _classFactory);
+ ModuleDef md = new DefaultModuleDefImpl(NonStaticBindMethodModule.class, logger, _classFactory);
// Prove that the bind method was not invoke
@@ -439,16 +426,12 @@
train_getServiceId(resources, "StringHolder");
train_getLogger(resources, logger);
train_getServiceInterface(resources, StringHolder.class);
- train_getService(
- resources,
- "ToUpperCaseStringHolder",
- StringHolder.class,
- new ToUpperCaseStringHolder());
+ train_getService(resources, "ToUpperCaseStringHolder", StringHolder.class, new ToUpperCaseStringHolder());
replay();
- ModuleDef def = new DefaultModuleDefImpl(MutlipleAutobuildServiceConstructorsModule.class,
- logger, _classFactory);
+ ModuleDef def = new DefaultModuleDefImpl(MutlipleAutobuildServiceConstructorsModule.class, logger,
+ _classFactory);
ServiceDef sd = def.getServiceDef("StringHolder");
@@ -481,8 +464,7 @@
assertTrue(ex
.getMessage()
.matches(
- "Error invoking service binder method org.apache.tapestry.ioc.internal.ExceptionInBindMethod.bind\\(ServiceBinder\\) "
- + "\\(at ExceptionInBindMethod.java:\\d+\\): Really, how often is this going to happen\\?"));
+ "Error invoking service binder method org.apache.tapestry.ioc.internal.ExceptionInBindMethod.bind\\(ServiceBinder\\) " + "\\(at ExceptionInBindMethod.java:\\d+\\): Really, how often is this going to happen\\?"));
}
verify();
@@ -495,8 +477,7 @@
replay();
- ModuleDef md = new DefaultModuleDefImpl(EagerLoadViaAnnotationModule.class, logger,
- _classFactory);
+ ModuleDef md = new DefaultModuleDefImpl(EagerLoadViaAnnotationModule.class, logger, _classFactory);
ServiceDef sd = md.getServiceDef("Runnable");
@@ -566,7 +547,12 @@
ServiceDef sd = md.getServiceDef("SurprisinglyBlueGreeter");
// BlueMarker from ServiceBindingOptions, RedMarker from @Marker on class
- assertEquals(sd.getMarkers(), CollectionFactory.newSet(RedMarker.class, BlueMarker.class));
+
+ Set<Class> markers = sd.getMarkers();
+
+ assertTrue(markers.contains(RedMarker.class));
+ assertTrue(markers.contains(BlueMarker.class));
+ assertEquals(markers.size(), 2);
verify();
}
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ModuleImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ModuleImplTest.java?rev=595970&r1=595969&r2=595970&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ModuleImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ModuleImplTest.java Sat Nov 17 08:36:50 2007
@@ -42,8 +42,7 @@
ClassFactory factory = new ClassFactoryImpl();
ServiceActivityTracker tracker = mockServiceActivityTracker();
- ModuleDef moduleDef = new DefaultModuleDefImpl(ModuleImplTestModule.class, logger,
- getClassFactory());
+ ModuleDef moduleDef = new DefaultModuleDefImpl(ModuleImplTestModule.class, logger, getClassFactory());
Module module = new ModuleImpl(registry, tracker, moduleDef, null, logger);
@@ -79,8 +78,7 @@
verify();
}
- protected final void train_newClass(InternalRegistry registry, ClassFactory factory,
- Class serviceInterface)
+ protected final void train_newClass(InternalRegistry registry, ClassFactory factory, Class serviceInterface)
{
expect(registry.newClass(serviceInterface)).andReturn(factory.newClass(serviceInterface));
}
@@ -156,10 +154,8 @@
}
catch (RuntimeException ex)
{
- assertEquals(
- ex.getMessage(),
- "Module builder class org.apache.tapestry.ioc.internal.PrivateConstructorModule "
- + "does not contain any public constructors.");
+ assertEquals(ex.getMessage(),
+ "Module builder class org.apache.tapestry.ioc.internal.PrivateConstructorModule " + "does not contain any public constructors.");
}
verify();
@@ -213,13 +209,13 @@
UpcaseService us = registry.getService(UpcaseService.class);
assertEquals(us.upcase("hello"), "HELLO");
- assertEquals(
- us.toString(),
- "<Proxy for Upcase(org.apache.tapestry.ioc.internal.UpcaseService)>");
+ assertEquals(us.toString(), "<Proxy for Upcase(org.apache.tapestry.ioc.internal.UpcaseService)>");
ToStringService ts = registry.getService(ToStringService.class);
assertEquals(ts.toString(), "<ToStringService: ToString>");
+
+ registry.shutdown();
}
@Test
@@ -238,6 +234,8 @@
{
// The details are checked elsewhere.
}
+
+ registry.shutdown();
}
}
Added: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ServiceProxySerializationTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ServiceProxySerializationTest.java?rev=595970&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ServiceProxySerializationTest.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry/ioc/internal/ServiceProxySerializationTest.java Sat Nov 17 08:36:50 2007
@@ -0,0 +1,83 @@
+package org.apache.tapestry.ioc.internal;
+
+import org.apache.tapestry.ioc.Registry;
+import org.apache.tapestry.ioc.services.TypeCoercer;
+import org.apache.tapestry.ioc.test.IOCTestCase;
+import org.testng.annotations.Test;
+
+import java.io.*;
+
+public class ServiceProxySerializationTest extends IOCTestCase
+{
+ @Test
+ public void serialization_deserialization() throws Exception
+ {
+ Registry r = buildRegistry();
+
+ TypeCoercer proxy = r.getService(TypeCoercer.class);
+
+ byte[] serialized = serialize(proxy);
+
+ TypeCoercer proxy2 = deserialize(TypeCoercer.class, serialized);
+
+ assertSame(proxy2, proxy, "De-serialized proxy is same object if Registry unchanged.");
+
+ r.shutdown();
+
+ r = buildRegistry();
+
+ TypeCoercer proxy3 = deserialize(TypeCoercer.class, serialized);
+
+ assertNotNull(proxy3);
+ assertNotSame(proxy3, proxy, "New proxy should be different, as it is from a different Registry.");
+
+ r.shutdown();
+ }
+
+ @Test
+ public void deserialize_with_no_registry() throws Exception
+ {
+ Registry r = buildRegistry();
+
+ TypeCoercer proxy = r.getService(TypeCoercer.class);
+
+ byte[] serialized = serialize(proxy);
+
+ r.shutdown();
+
+ try
+ {
+ deserialize(TypeCoercer.class, serialized);
+ unreachable();
+ }
+ catch (Exception ex)
+ {
+ assertMessageContains(ex,
+ "Service token for service 'TypeCoercer' can not be converted back into a proxy because no proxy provider has been registered");
+ }
+ }
+
+ private byte[] serialize(Object object) throws IOException
+ {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+
+ oos.writeObject(object);
+
+ oos.close();
+
+ byte[] serialized = baos.toByteArray();
+ return serialized;
+ }
+
+ private <T> T deserialize(Class<T> type, byte[] serialized) throws IOException, ClassNotFoundException
+ {
+ ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(serialized));
+
+ Object raw = ois.readObject();
+
+ ois.close();
+
+ return type.cast(raw);
+ }
+}