> Perhaps we need complement the addInstance() methods with > addProxy() methods on the Configuration interfaces?
Actually, this would be nice for a couple of times now I've been bit by having config.addInstance("blah", OptionalImpl.class); where OptionalImpl references a jar that's no longer deployed resulting in an "Exception constructing service" when the contribution finally gets used. The fix is simple enough, binding OptionalImpl as a service and injecting it via @Local into the contribution method. But changing the one line to: config.addProxy("blah", OptionalImpl.class); would be much shorter and cleaner! Steve. On 28 February 2012 01:43, Howard Lewis Ship <hls...@gmail.com> wrote: > FYI: http://tapestryjava.blogspot.com/2012/02/plastic-advanced-example.html > > > On Mon, Feb 27, 2012 at 8:45 AM, Howard Lewis Ship <hls...@gmail.com> wrote: >> On Fri, Feb 24, 2012 at 9:14 AM, Blower, Andy >> <andy.blo...@proquest.co.uk> wrote: >>> Sorry, premature celebration. :-( >>> >>> It works until the proxy is serialized, which throws a >>> NotSerializableException. In normal binding / override the proxy is a >>> JustInTimeObjectCreator and using this proxy it seems to be a >>> ReloadableObjectCreator, but nether of them are marked as Serializable so >>> I'm not sure how it normally works. My understanding was that SSO's could >>> hold references to services since these were simply referring to a proxy >>> which essentially could be serialized and replicated across a cluster since >>> it only sent a token. >> >> The code for this is hidden inside ModuleImpl.createProxyInstance() >> which creates a proxy that implements Serializable, and the optional >> writeReplace() method. See all ModuleImpl.createProxy(). >> >> Basically, the proxy uses writeReplace() to write a ServiceProxyToken >> into the output stream; when the stream is deserialized, the >> ServiceProxyToken uses a static field to locate the Registry, and >> replaces itself with the service. >> >> If there is a way to @Inject a @Local service to contribute to >> ServiceOverrides, that will work better, as the local service will >> have it own proxy & ServiceProxyToken. Much like the second example >> on http://tapestry.apache.org/ioc-cookbook-overriding-ioc-services.html >> >> But I'm not sure how this affects your original problem. >> >> You may find it is easier to use either method advice, or service >> decoration, to augment the existing service in place, rather than >> replace it entirely. >> >> In fact, this does point to the idea that Tapestry could use a new >> type of module method for replacing built-in services with >> replacements cleanly, rather than rely on ServiceOverrides. Such a >> module method (and related RegistrtyImpl support) would make the >> replacement hide behind the original service's id and >> ServiceProxyToken. >> >> >>> >>> How far out am I here? >>> >>> >>> -----Original Message----- >>> From: Blower, Andy [mailto:andy.blo...@proquest.co.uk] >>> Sent: 22 February 2012 17:35 >>> To: Tapestry users >>> Subject: RE: [T5.3] Contributing a Service Override using addInstance() >>> >>> Yes that works! I had no idea you could do such a thing as I'd not see it >>> anywhere in the documentation. >>> >>> I don't know if an addProxy() method is worth adding, our requirements seem >>> quite unusual. If it would be useful to other Tapestry users then maybe. >>> >>> Thanks for the reply Howard. >>> >>> -----Original Message----- >>> From: Howard Lewis Ship [mailto:hls...@gmail.com] >>> Sent: 21 February 2012 19:51 >>> To: Tapestry users >>> Subject: Re: [T5.3] Contributing a Service Override using addInstance() >>> >>> This might work: >>> >>> @Contribute(ServiceOverride.class) >>> >>> public static void >>> setupApplicationServiceOverrides(MappedConfiguration<Class,Object> >>> configuration, ObjectLocator locator) >>> >>> { >>> SomeServiceType override = locator.proxy(SomeServiceType.class, >>> SomeServiceTypeOverrideImpl.class); >>> >>> configuration.add(SomeServiceType.class, override); >>> >>> } >>> >>> >>> This contributes a proxy for the override, rather than the override itself >>> ... meaning that eventual construction of SomeServiceTypeOverrideImpl is >>> deferred until needed, and that will be after the MasterObjectProvider and >>> ServicesOverride are constructed. >>> >>> Give it a try and report back! >>> >>> Perhaps we need complement addInstance() methods with addProxy() methods on >>> the Configuration/OrderedConfiguration/MappedConfiguration >>> interfaces? >>> >>> >>> On Tue, Feb 21, 2012 at 6:33 AM, Blower, Andy <andy.blo...@proquest.co.uk> >>> wrote: >>>> Thanks for the reply Steve. The two classes I mention are Tapestry IoC >>>> classes, not my own. >>>> >>>> What you describe is how most of our overrides are implemented but this >>>> one is conditional - we only need to override this service in a specific >>>> environment and that's what causes the issue. If I define it like that if >>>> the override is not applied then the IoC has two implementations bound (if >>>> you don't bind it you can't have it injected into the override method) and >>>> will throw errors whenever the service is injected without a specific ID. >>>> There are 100's of places where we have plain injections and is not >>>> practical to change them. >>>> >>>> >>>> -----Original Message----- >>>> From: Steve Eynon [mailto:steve.ey...@alienfactory.co.uk] >>>> Sent: 21 February 2012 10:36 >>>> To: Tapestry users >>>> Subject: Re: [T5.3] Contributing a Service Override using >>>> addInstance() >>>> >>>> Hi, I'm not really sure what's going on as the two classes you mention, >>>> ValidatingMappedConfigurationWrapper & AbstractConfigurationImpl, don't >>>> appear in your code snippet. >>>> >>>> If you define your overriding service as an Interface (say in the >>>> bind() method) then T5 will create a proxy for it. >>>> >>>> public static void bind(ServiceBinder binder) { >>>> binder.bind(ToOverrideInterface.class, >>>> ToOverrideImpl.class).withId("anything so we don't conflict with the >>>> existing ID"); } >>>> >>>> then you can inject that in the service override like this: >>>> >>>> public static void contributeServiceOverride(MappedConfiguration >>>> config, @Local ToOverrideInterface override) { >>>> config.add(ToOverrideInterface.class, override); } >>>> >>>> The @Local is important, otherwise T5 doesn't know which serivce to inject >>>> (yours or the one you're trying to override). >>>> >>>> Steve. >>>> >>>> >>>> On 20 February 2012 20:54, Blower, Andy <andy.blo...@proquest.co.uk> wrote: >>>>> I managed to get this to work by tracking down all dependencies and >>>>> finding that one was being used in the services' constructor. Once I >>>>> moved the initialisation code into a lazy init method I stopped getting >>>>> the exceptions. >>>>> >>>>> Unfortunately, I still have an issue because when using addInstance() >>>>> Tapestry is not using a proxy for the overriding service implementation, >>>>> instead I'm getting a concrete reference instead which I thought never >>>>> happened with Tapestry IoC. This causes problems when used in objects >>>>> that are serialized to the session because it tries to serialize the >>>>> service implementation rather than just the service proxy. >>>>> >>>>> My override looks like this: >>>>> >>>>> @Contribute(ServiceOverride.class) >>>>> public static void >>>>> setupApplicationServiceOverrides(MappedConfiguration<Class<?>, >>>>> Object> >>>>> configuration) >>>>> { >>>>> configuration.addInstance(ProductConfig.class, >>>>> DynamicMultiProductConfig.class); >>>>> } >>>>> >>>>> Basically the contributionType in ValidatingMappedConfigurationWrapper >>>>> (AbstractConfigurationImpl) is Object which isn't an interface so a proxy >>>>> isn't created. How can I change the signature of my module service >>>>> override method so that contributionType is an interface and I get a >>>>> service proxy like every other service? >>>>> >>>>> Can anyone help me? >>>>> >>>>> >>>>> -----Original Message----- >>>>> From: Blower, Andy [mailto:andy.blo...@proquest.co.uk] >>>>> Sent: 15 February 2012 14:51 >>>>> To: users@tapestry.apache.org >>>>> Subject: [T5.3] Contributing a Service Override using addInstance() >>>>> >>>>> I've read the section below about contributing a service override. This >>>>> method is exactly what I need to resolve an issue I'm having getting a >>>>> conditional override implemented, but it doesn't appear to work if the >>>>> service implementations' constructor has any other T5 service >>>>> dependencies in the signature. (T5 complains that ServiceOverride depends >>>>> on itself. >>>>> >>>>> Is this true, because that doesn't seem to be what's implied below by >>>>> "handle dependency resolution", and makes addInstance of limited >>>>> usefulness. I'm hoping I'm just missing something here. >>>>> >>>>> >>>>> >>>>> From http://tapestry.apache.org/ioc-cookbook-overriding-ioc-services.html >>>>> : >>>>> >>>>> "In this case, it is very easy to supply your own alternate >>>>> implementation of a service. >>>>> AppModule.java (partial) >>>>> >>>>> @Contribute(ServiceOverride.class) >>>>> >>>>> public static void >>>>> setupApplicationServiceOverrides(MappedConfiguration<Class,Object> >>>>> configuration) >>>>> >>>>> { >>>>> >>>>> configuration.addInstance(SomeServiceType.class, >>>>> SomeServiceTypeOverrideImpl.class); >>>>> >>>>> } >>>>> >>>>> The name of the method is not important, as long as the >>>>> @Contribute<http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/Contribute.html> >>>>> annotation is present on the method. >>>>> >>>>> In this example, we are using addInstance() which will instantiate the >>>>> indicated class and handle dependency resolution. (Be careful with this, >>>>> because in some cases, resolving dependencies of the override class can >>>>> require checking against the ServiceOverrides service, and you'll get a >>>>> runtime exception about ServiceOverrides requiring itself!)" >>>>> >>>>> >>>>> >>>>> --------------------------------------------------------------------- >>>>> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org >>>>> For additional commands, e-mail: users-h...@tapestry.apache.org >>>>> >>>> >>>> --------------------------------------------------------------------- >>>> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org >>>> For additional commands, e-mail: users-h...@tapestry.apache.org >>>> >>>> >>>> >>>> >>>> --------------------------------------------------------------------- >>>> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org >>>> For additional commands, e-mail: users-h...@tapestry.apache.org >>>> >>> >>> >>> >>> -- >>> Howard M. Lewis Ship >>> >>> Creator of Apache Tapestry >>> >>> The source for Tapestry training, mentoring and support. Contact me to >>> learn how I can get you up and productive in Tapestry fast! >>> >>> (971) 678-5210 >>> http://howardlewisship.com >>> >>> --------------------------------------------------------------------- > > > > -- > Howard M. Lewis Ship > > Creator of Apache Tapestry > > The source for Tapestry training, mentoring and support. Contact me to > learn how I can get you up and productive in Tapestry fast! > > (971) 678-5210 > http://howardlewisship.com > > --------------------------------------------------------------------- > To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org > For additional commands, e-mail: users-h...@tapestry.apache.org > --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org