More comments inline.

Thanks,
Raymond

----- Original Message ----- From: "Simon Laws" <[EMAIL PROTECTED]>
To: <[email protected]>
Sent: Tuesday, September 04, 2007 10:37 AM
Subject: Re: @Conversational + @Scope("REQUEST") Test


On 9/4/07, Raymond Feng <[EMAIL PROTECTED]> wrote:

Comments inline.

Thanks,
Raymond

----- Original Message -----
From: "Simon Laws" <[EMAIL PROTECTED]>
To: <[email protected]>
Sent: Tuesday, September 04, 2007 5:57 AM
Subject: Re: @Conversational + @Scope("REQUEST") Test


> On 9/4/07, Simon Laws <[EMAIL PROTECTED]> wrote:
>>
>>
>>
>> On 9/4/07, JunJie Nan <[EMAIL PROTECTED]> wrote:
>> >
>> > I tried to make some sense on @Conversational and @Scope("REQUEST"),
>> > but
>> > failed.  The error message:
>> > java.lang.ClassCastException: java.lang.String incompatible with
>> > java.lang.Thread
>> >     at
>> > org.apache.tuscany.sca.core.scope.RequestScopeContainer.getWrapper (
>> > RequestScopeContainer.java:35)
>> >     at
>> >
>> >
org.apache.tuscany.sca.implementation.java.invocation.JavaImplementationInvoker.getInstance
>> > (JavaImplementationInvoker.java:62)
>> >     at
>> >
>> >
org.apache.tuscany.sca.implementation.java.invocation.JavaImplementationInvoker.invoke
>> > (JavaImplementationInvoker.java:85)
>> >     at
>> >
org.apache.tuscany.sca.binding.sca.impl.RuntimeSCABindingInvoker.invoke(
>> > RuntimeSCABindingInvoker.java:48)
>> >     at
>> > org.apache.tuscany.sca.core.invocation.JDKInvocationHandler.invoke (
>> > JDKInvocationHandler.java:270)
>> >     at
>> > org.apache.tuscany.sca.core.invocation.JDKInvocationHandler.invoke(
>> > JDKInvocationHandler.java:114)
>> >     at $Proxy9.empty(Unknown Source)
>> >     at samples.hex.HexTest.testCartService (HexTest.java:77)
>> > I tried:
>> >
>> >    1.  @Conversational + @Scope("STATELESS")
>> >    2.  @Conversational + @Scope("CONVERSATION")
>> >    3.  @Conversational + @Scope("COMPOSITE")
>> >
>> > All the above 3 worked fine and did not have the error message >> > above.
>> >
>> > Anybody can give me some hints, thanks!
>> >
>> > The component definition:
>> >     <component name="CartComponent">
>> > <implementation.java >> > class="samples.hex.cart.impl.CartImpl"/>
>> >     </component>
>> >
>> > The implementation:
>> > package samples.hex.cart.impl;
>> >
>> > import java.util.HashMap;
>> > import java.util.Map;
>> >
>> > import org.osoa.sca.annotations.ConversationID;
>> > import org.osoa.sca.annotations.Destroy ;
>> > import org.osoa.sca.annotations.Init;
>> > import org.osoa.sca.annotations.Scope;
>> > import org.osoa.sca.annotations.Service;
>> >
>> > import samples.hex.cart.services.CartService;
>> >
>> > @Scope("REQUEST")
>> > @Service( CartService.class)
>> > public class CartImpl implements CartService {
>> >
>> >     @ConversationID
>> >     protected String conversationID;
>> >
>> >     protected Map<String, Integer> cart;
>> >     @Init
>> >     protected void init(){
>> >         if(cart==null)
>> >             cart = new HashMap<String, Integer>();
>> >     }
>> >
>> >     public void empty() {
>> >         cart.clear();
>> >     }
>> >
>> >     public Map<String, Integer> getItems() {
>> >         return cart;
>> >     }
>> >
>> >     public void updateItem(String itemID, int quantity) {
>> >         if(quantity<=0)
>> >             cart.remove(itemID);
>> >         cart.put(itemID, quantity);
>> >         System.out.println (conversationID + ":" + this);
>> >     }
>> >
>> >     @Destroy
>> >     protected void destroy(){
>> >         empty();
>> >     }
>> > }
>> >
>> > The interface:
>> > package samples.hex.cart.services;
>> >
>> > import java.util.Map ;
>> >
>> > import org.osoa.sca.annotations.Conversational;
>> >
>> > @Conversational
>> > public interface CartService{
>> >     public void updateItem(String itemID, int quantity);
>> >     public void empty();
>> >     public Map<String, Integer> getItems();
>> > }
>> >
>> > The Test Code:
>> >     @Test
>> >     public void testCartService(){
>> >         CartService cart = hex.getService(CartService.class,
>> > "CartComponent/CartService");
>> >         assertNotNull(cart);
>> >         cart.empty();
>> >     }
>> >
>> >
>> >
>> > --
>> > Cheers
>> > Jun Jie Nan
>> >   ? ??
>> > ?^o^??)~
>> >
>>
>> Hi JunJie
>>
>> I looks like you've found a bug. Can you raise a JIRA for this and >> I'll
>> take a look at it.
>>
>> Thanks
>>
>> Simon
>>
> There is a problem here.
>
> The cause of the problem is the RequestScopeContainer being defined as
an
> AbstractScopeContainer<Thread>. This forces the RequestScopeContainer > to
> implement
>
> public InstanceWrapper getWrapper(Thread contextId)
>
> Even though the container doesn't use the context id that's passed (It
> just
> uses the current thread object to find the right instance). During
> conversations the contextId is very unlikely to be a Thread. It's
usually
> a
> string but is sometimes something else.
>
> To fix this, without checking in the calling code what type is > expected,
> I've changed RequestScopeContainer to be a
AbstractScopeContainer<Object>.
> It still deals with Thread internally.

There might be cases that the contextID is a thread but it's different
than
the current one.

>
> Am just testing now but if anyone has any concerns let me know.

I think the key issue in in the JavaImplementationInvoker. At this moment,
it blindly uses the conversationID as the context ID without checking the
scope requirement.The following code may be better. We could even pass
null
as the context ID in this case.

Object contextId = null;
if (scopeContainer != null) {
    Scope scope = scopeContainer.getScope();
    if (scope == Scope.CONVERSATION) {
        contextId = msg.getConversationID();
    } else if (scope == Scope.REQUEST) {
        contextId = Thread.currentThread();
    }
}

>
> Simon
>


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

We could do.It fells a little odd to be testing what type a container is
expecting. I guess because the scope containers are presented rather
generically. So we either need to go down the route of making then all take
Object or checking what type is required before calling them. As I say the
second option feels a little strange but I don't have a string argument
against it. I'll change the fix to this if you like.


The context id is definitely scope-specific. Changing the signature of the method doesn't help us pass in the correct context id. The ideal situation is that the ScopeContainer can dig the id out from the context instead of having the caller to pass it in. For example, the ConversationScopeContainer may expect the conversationID available from a thread local variable. The bottom line is that the current context id need to be made visible to the scope container.

Simon



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to