On 9/4/07, Raymond Feng <[EMAIL PROTECTED]> wrote: > > 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]
I'll go with the original suggestion for now. I think you are right re. context passing but I'm going to leave that as a separate issue for the time being as I don't have a good enough grasp on how/where context is used and transformed and I expect that it could do with wider attention than just this. Simon
