3 Replies Latest reply on Feb 5, 2002 12:51 PM by armint

    jboss lets many threads into the same business method simult

    sylwia


      I was trying to check wether jboss would let many clients connect to the same business method in an entity bean at the same time, and I found out, howerer to invoke this business method (through a session bean, or directly), it does.
      I was also changing value of 'reentrant' parameter, but it didn't help.

      This is the piece of code of my entity bean (startTest is a business method), where I was trying to count threads that got into it.


      private ArrayList threads = new ArrayList();

      public void startTest() {
      in();
      try {
      Thread.sleep(2000);
      } catch (InterruptedException ex) {
      logger.fatal("I was woke up! ");
      }
      out();
      }

      private synchronized void in() {
      String name = Thread.currentThread().getName();
      if (threads.size()>0)
      logger.fatal(" MORE THAN ONE THREAD!!!!!! ");
      threads.add(name);
      }

      private synchronized void out() {
      threads.remove(Thread.currentThread().getName());
      }




      I didn't find in ejb2.0 specification much about how many clients should be able to invoke the same business method in an entity bean. Anyway if it is more than one, this can be rather unsafe.

      Is there a way to prevent such situation while designing an entity bean? Is it situation normal, or maybe I made a mistake?

      Thanks for your reply.


      sylwia

        • 1. Re: jboss lets many threads into the same business method si
          davidjencks

          This shouldn't happen. Can you provide the rest of your (calling) code and a bit of log? also which jboss, jboss.xml, etc.

          • 2. Re: jboss lets many threads into the same business method si
            sylwia

            This is rest of the entity bean code. Not much interesting...


            public class EntityTestBean implements EntityBean {
            public static transient Category logger = Category.getInstance(EntityTestBean.class.getName());
            private transient EntityContext context;
            private Long key = new Long(1);
            private ArrayList threads = new ArrayList();


            public void startTest() {
            in();
            try {
            Thread.sleep(2000);
            } catch (InterruptedException ex) {
            logger.fatal("I was woke up! " + Thread.currentThread().getName());
            }
            out();
            }

            private synchronized void in() {
            String name = Thread.currentThread().getName();
            logger.debug("current thread: " + name);
            if (threads.size()>0)
            logger.fatal(" MORE THAN ONE THREAD!!!!!! ");
            threads.add(name);
            }

            private synchronized void out() {
            threads.remove(Thread.currentThread().getName());
            }


            public Long ejbCreate() {
            return new Long(1);
            }
            public void ejbPostCreate() {
            }
            public Long ejbFindByPrimaryKey(Long key) throws FinderException {
            if( !key.equals(new Long(1)) )
            throw new EJBException("Wrong initial key ");
            return key;
            }
            public void ejbRemove() {
            }
            public void setEntityContext(EntityContext context) {
            this.context = context;
            }
            public void unsetEntityContext() {
            }
            public void ejbActivate() {
            key = (Long)context.getPrimaryKey();
            }
            public void ejbPassivate() {
            key = null;
            }
            public void ejbLoad() {
            }
            public void ejbStore() {
            }
            }


            Clients code:

            public class Client {

            public static void main(String[] args) {

            Tester tester = new Tester();
            }

            }

            public class Tester implements Runnable {

            static Long key;

            public Tester() {
            key = new Long(1);

            for(int i=0; i<10; i++ ) {
            Thread t = new Thread(this);
            t.setName(new Integer(i).toString());
            t.start();
            try {
            t.sleep(1000);
            } catch (InterruptedException ex) {
            System.out.println("I was woke up! " + Thread.currentThread().getName() );
            }
            }
            }

            public void run() {
            System.out.println( "--- now working nr " + Thread.currentThread().getName() + " ... " );
            testEntityBean( Thread.currentThread().getName() );
            }


            private void testEntityBean(String name) {
            System.out.println("Testing EntityBean with key = " + key + "...");
            try {
            Context initial = new InitialContext();
            Object objref = initial.lookup("EntityBeanEJB");

            EntityTestHome home = (EntityTestHome)PortableRemoteObject.narrow(objref, EntityTestHome.class);
            EntityTest test = (EntityTest)home.findByPrimaryKey(key);

            System.out.println("start tests ... ");
            test.startTest();
            }
            catch (Exception ex) {
            System.out.println("Caught an unexpected exception!");
            ex.printStackTrace();
            }
            }

            }


            ejb-jar.xml:


            <?xml version="1.0" encoding="ISO-8859-1"?>

            <ejb-jar>
            IAU application JBossTests
            <display-name>IAUApplication JBossTests</display-name>
            <enterprise-beans>

            <!-- SessionBeanEJB -->

            <ejb-name>SessionBeanEJB</ejb-name>
            com.efigence.jbossTests.session.SessionTestHome
            com.efigence.jbossTests.session.SessionTest
            <ejb-class>com.efigence.jbossTests.session.SessionTestBean</ejb-class>
            <session-type>Stateful</session-type>
            <transaction-type>Container</transaction-type>
            <ejb-ref>
            <ejb-ref-name>entity/EntityBeanEJB</ejb-ref-name>
            <ejb-ref-type>Entity</ejb-ref-type>
            com.efigence.jbossTests.entity.EntityTestHome
            com.efigence.jbossTests.entity.EntityTest
            <ejb-link>EntityBeanEJB</ejb-link>
            </ejb-ref>

            <!-- EntityBeanEJB -->

            <ejb-name>EntityBeanEJB</ejb-name>
            com.efigence.jbossTests.entity.EntityTestHome
            com.efigence.jbossTests.entity.EntityTest
            <ejb-class>com.efigence.jbossTests.entity.EntityTestBean</ejb-class>
            <persistence-type>Bean</persistence-type>
            <prim-key-class>java.lang.Long</prim-key-class>
            True


            </enterprise-beans>

            <assembly-descriptor>
            <container-transaction>
            Entity Bean

            <ejb-name>EntityBeanEJB</ejb-name>
            <method-name>*</method-name>

            <trans-attribute>Required</trans-attribute>
            </container-transaction>
            </assembly-descriptor>
            </ejb-jar>


            jboss.xml:

            <?xml version="1.0" encoding="UTF-8"?>


            <enterprise-beans>

            <ejb-name>SessionBeanEJB</ejb-name>



            <ejb-name>EntityBeanEJB</ejb-name>

            </enterprise-beans>



            Code of my session bean does exactly the same think that client: connects to entity bean and runs startTest() method.

            I guess this test is extremely simple, anyway, there may be something wrong in it.

            • 3. Re: jboss lets many threads into the same business method si
              armint

              There are two things that may be creating problems. First, the spec disallows the keyword synchronized. The spec, also, prohibits thread management which I think includes Thread.sleep(). What happens if you remove synchronized from the two methods? If you are worried about concurrent access to the ArrayList use Vector. And, instead of Thread.sleep(), try using a long running loop. These changes might not make a difference, but I think they are worth investigating.