users@glassfish.java.net

Problem (bug?) using _at_EJB annotation

From: <glassfish_at_javadesktop.org>
Date: Wed, 21 Mar 2007 07:51:05 PST

The situation is following.
There is stateless bean that has dependency with stateful bean. And some method of stateless bean returns instance of stateful bean to client. This can be used when modelling Iterator pattern using SF bean.

So this is simple code:

@Remote
public interface SFSBA
{
        public void foo1();
}

...

@Stateful
public class SFSBAImpl implements SFSBA
{
        public void foo1()
        {
                for (int i = 0; i < 1000000; i++)
                {
                        Math.sin(i);
                }
        }
}

...

@Remote
public interface SLSBA
{
        SFSBA getSFSB();

        SFSBA getSFSBByLookup();
}

...

@Stateless
public class SLSBAImpl implements SLSBA
{
        @EJB
        private SFSBA sfsb;

        @Resource
        private SessionContext ctx;

        public SFSBA getSFSB()
        {
                return sfsb;
        }
        public SFSBA getSFSBByLookup()
        {
                return (SFSBA)ctx.lookup("stateful");
        }
}

...

<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd">
        <enterprise-beans>
                <session>
                        <ejb-name>SLSBAImpl</ejb-name>
                        <ejb-ref>
                                <ejb-ref-name>stateful</ejb-ref-name>
                                <remote>ru.tests.ejb.sf.SFSBA</remote>
                        </ejb-ref>
                </session>
        </enterprise-beans>
</ejb-jar>

...

public class Test1
{
        @Test
        public void test11() throws NamingException, InterruptedException
        {
                InitialContext ctx = new InitialContext();
                Thread t1 = new TestThread(ctx);
                Thread t2 = new TestThread(ctx);
                t1.start();
                t2.start();
                t1.join();
                t2.join();

        }

        private class TestThread extends Thread
        {
                private InitialContext ctx;

                public TestThread(InitialContext ctx)
                {
                        this.ctx = ctx;
                }

                public void run()
                {
                        try
                        {
                                SLSBA slsba;
                                synchronized (ctx)
                                {
                                        slsba = (SLSBA)ctx.lookup(SLSBA.class.getCanonicalName());
                                }
                                //slsba.getSFSB().foo1(); // here is EXCEPITION!
                                slsba.getSFSBByLookup().foo1(); // here is OK!

                        }
                        catch (NamingException e)
                        {
                                throw new RuntimeException(e);
                        }
                }
        }
}


The problem is that when two different clients (simulated by two threads) get SF beans and then call some method on them exception is got:

Caused by: javax.ejb.ConcurrentAccessException: SessionBean is executing another request. [session-key: 7d90c02200a81f-752fe1cd-1]
...

As I understand when using @EJB annotation the same instance of stateful bean is returned to different clients.
Using direct sessionContext.lookup is ok.

Any thoughts?
[Message sent by forum member 'hazurek' (hazurek)]

http://forums.java.net/jive/thread.jspa?messageID=209225