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]