> 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

Reply via email to