3 Replies Latest reply on Mar 17, 2005 2:15 PM by belaban

    ConcurrentModificationException in TransactionTable

      Hi,

      I put jboss-cache.jar of JBossCache1.2.1 into JBoss4.0.0. And I tested a web-application in the JBoss with heavy load.

      environment:
      Redhat Enterprise 3.0
      JDK 1.4.2
      JBoss 4.0.0?with jboss-cache.jar of JBossCache1.2.1?
      2 node cluster
      load-balanced by Apache2+mod_jk2
      http session replication enabled
      replication-trigger SET
      replication-granularity SESSION

      I got the following Exception.

      2005-03-17 11:30:25,703 ERROR [org.jgroups.blocks.RpcDispatcher] failed invoking method
      java.util.ConcurrentModificationException
       at java.util.HashMap$HashIterator.nextEntry(HashMap.java:782)
       at java.util.HashMap$EntryIterator.next(HashMap.java:824)
       at org.jboss.cache.TransactionTable.getLocalTransaction(TransactionTable.java:71)
       at org.jboss.cache.interceptors.ReplicationInterceptor.replicate(ReplicationInterceptor.java:187)
       at org.jboss.cache.TreeCache._replicate(TreeCache.java:2682)
       at sun.reflect.GeneratedMethodAccessor74.invoke(Unknown Source)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:324)
       at org.jgroups.blocks.MethodCall.invoke(MethodCall.java:236)
       at org.jgroups.blocks.RpcDispatcher.handle(RpcDispatcher.java:220)
       at org.jgroups.blocks.RequestCorrelator.handleRequest(RequestCorrelator.java:615)
       at org.jgroups.blocks.RequestCorrelator.receiveMessage(RequestCorrelator.java:512)
       at org.jgroups.blocks.RequestCorrelator.receive(RequestCorrelator.java:326)
       at org.jgroups.blocks.MessageDispatcher$ProtocolAdapter.handleUp(MessageDispatcher.java:722)
       at org.jgroups.blocks.MessageDispatcher$ProtocolAdapter.access$300(MessageDispatcher.java:554)
       at org.jgroups.blocks.MessageDispatcher$1.run(MessageDispatcher.java:691)
       at java.lang.Thread.run(Thread.java:534)


      I checked org.jboss.cache.TransactionTable.
      tx_map is synchronized in getLocalTransaction(GlobalTransaction gtx), but tx_map may be modified in put(Transaction tx, GlobalTransaction gtx) or remove(Transaction tx).
      I guess some synchronized blocks are needed like:

      public void put(Transaction tx, GlobalTransaction gtx) {
       if(tx == null) {
       log.error("key (Transaction) is null");
       return;
       }
       synchronized(tx_map) {
       tx_map.put(tx, gtx);
       }
       }


      public GlobalTransaction remove(Transaction tx) {
       if(tx == null)
       return null;
       GlobalTransaction gtx = null;
       synchronized(tx_map) {
       gtx = (GlobalTransaction)tx_map.remove(tx);
       }
       return gtx;
       }


      Is this irrelevant ?