Uploaded image for project: 'ModeShape'
  1. ModeShape
  2. MODE-2336

Unstable work event listener monitor changes with user transactions

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • Blocker
    • 3.8.x-prod-ip6.1, 4.1.0.Final
    • 3.7.4.Final, 4.0.0.Final, 3.8.1.Final
    • JCR
    • None
    • Hide
      @Test
      public void listenerAdapterExceptionTest() throws RepositoryException, NotSupportedException, SystemException, SecurityException,
               IllegalStateException, RollbackException, HeuristicMixedException, HeuristicRollbackException,
               InterruptedException {
           // initialize workspace
           Session session = getSession();
           session.getRootNode().addNode("folder1");
           session.save();
           // register listener for PropertyEvent with nodeType restriction
           Session listenerSession = repository().login();
           EventListener listener = new EventListener() {
      
               public void onEvent(EventIterator events) {
                   while (events.hasNext()) {
                       Event event = events.nextEvent();
                       System.out.println(event.toString());
                   }
               }
           };
           TransactionManager txman = repository().transactionManager();
           listenerSession
                   .getWorkspace()
                   .getObservationManager()
                   .addEventListener(listener, Event.PROPERTY_ADDED | Event.PROPERTY_REMOVED | Event.PROPERTY_CHANGED,
                           "/folder1", true, null, new String[] { "nt:unstructured" }, false);
           // try to add nodes within transactions
           for (int i = 0; i < 1000; i++) {
               txman.begin();
               Session session1 = repository().login();
               session1.getNode("/folder1").addNode("node" + i);
               session1.save();
               session1.logout();
               txman.commit();
           }
           // wait for listener thread
           Thread.sleep(1000);
           // clean
           listenerSession.getWorkspace().getObservationManager().removeEventListener(listener);
           listenerSession.logout();
           // check system out
      }
      
      @Test
      public void catchExceptionTest() throws RepositoryException, NotSupportedException, SystemException, SecurityException,
               IllegalStateException, RollbackException, HeuristicMixedException, HeuristicRollbackException,
               InterruptedException {
           // initialize workspace
           Session session = getSession();
           session.getRootNode().addNode("folder2");
           session.save();
           // register NODE_ADDED listener
           final Session listenerSession = repository().login();
           final ArrayList<Event> failedEvents = new ArrayList<Event>();
           EventListener listener = new EventListener() {
      
               public void onEvent(EventIterator events) {
                   while (events.hasNext()) {
                       Event event = events.nextEvent();
                       try {
                           // try to find created node
                           listenerSession.getNode(event.getPath());
                       } catch (RepositoryException e) {
                           // register fails
                           failedEvents.add(event);
                           e.printStackTrace();
                       }
                       System.out.println(event.toString());
                   }
               }
           };
           listenerSession.getWorkspace().getObservationManager()
                   .addEventListener(listener, Event.NODE_ADDED, "/folder2", true, null, null, false);
           TransactionManager txman = repository().transactionManager();
           // try to add nodes within transactions
           int transactions = 1000;
           for (int i = 0; i < transactions; i++) {
               txman.begin();
               Session session1 = repository().login();
               session1.getNode("/folder2").addNode("node" + i);
               session1.save();
               session1.logout();
               txman.commit();
           }
           // wait for listener thread
           Thread.sleep(1000);
           // clean
           listenerSession.getWorkspace().getObservationManager().removeEventListener(listener);
           listenerSession.logout();
           // assert result
           Assert.assertEquals("Failed events", 0 + " / " + transactions,
                failedEvents.size() + " / " + transactions);
      }
      
      Show
      @Test public void listenerAdapterExceptionTest() throws RepositoryException, NotSupportedException, SystemException, SecurityException, IllegalStateException, RollbackException, HeuristicMixedException, HeuristicRollbackException, InterruptedException { // initialize workspace Session session = getSession(); session.getRootNode().addNode( "folder1" ); session.save(); // register listener for PropertyEvent with nodeType restriction Session listenerSession = repository().login(); EventListener listener = new EventListener() { public void onEvent(EventIterator events) { while (events.hasNext()) { Event event = events.nextEvent(); System .out.println(event.toString()); } } }; TransactionManager txman = repository().transactionManager(); listenerSession .getWorkspace() .getObservationManager() .addEventListener(listener, Event.PROPERTY_ADDED | Event.PROPERTY_REMOVED | Event.PROPERTY_CHANGED, "/folder1" , true , null , new String [] { "nt:unstructured" }, false ); // try to add nodes within transactions for ( int i = 0; i < 1000; i++) { txman.begin(); Session session1 = repository().login(); session1.getNode( "/folder1" ).addNode( "node" + i); session1.save(); session1.logout(); txman.commit(); } // wait for listener thread Thread .sleep(1000); // clean listenerSession.getWorkspace().getObservationManager().removeEventListener(listener); listenerSession.logout(); // check system out } @Test public void catchExceptionTest() throws RepositoryException, NotSupportedException, SystemException, SecurityException, IllegalStateException, RollbackException, HeuristicMixedException, HeuristicRollbackException, InterruptedException { // initialize workspace Session session = getSession(); session.getRootNode().addNode( "folder2" ); session.save(); // register NODE_ADDED listener final Session listenerSession = repository().login(); final ArrayList<Event> failedEvents = new ArrayList<Event>(); EventListener listener = new EventListener() { public void onEvent(EventIterator events) { while (events.hasNext()) { Event event = events.nextEvent(); try { // try to find created node listenerSession.getNode(event.getPath()); } catch (RepositoryException e) { // register fails failedEvents.add(event); e.printStackTrace(); } System .out.println(event.toString()); } } }; listenerSession.getWorkspace().getObservationManager() .addEventListener(listener, Event.NODE_ADDED, "/folder2" , true , null , null , false ); TransactionManager txman = repository().transactionManager(); // try to add nodes within transactions int transactions = 1000; for ( int i = 0; i < transactions; i++) { txman.begin(); Session session1 = repository().login(); session1.getNode( "/folder2" ).addNode( "node" + i); session1.save(); session1.logout(); txman.commit(); } // wait for listener thread Thread .sleep(1000); // clean listenerSession.getWorkspace().getObservationManager().removeEventListener(listener); listenerSession.logout(); // assert result Assert.assertEquals( "Failed events" , 0 + " / " + transactions, failedEvents.size() + " / " + transactions); }

    Description

      When add nodes within transaction and has registered EventListener with nodeType restriction, sometimes happen exceptions logged by EventListenerAdapter (showcase in listenerAdapterExceptionTest):

      org.modeshape.jcr.JcrObservationManager$ChangeSetConverter
      acceptBasedOnNodeTypeName
      SEVERE: Error checking primary type 'null' with mixins of 'null' against type names of '[nt:unstructured]'
      javax.jcr.PathNotFoundException: No node exists at path '/folder1/node69' in workspace "default"
           at org.modeshape.jcr.JcrSession.cachedNode(JcrSession.java:623)
           at org.modeshape.jcr.JcrSession.node(JcrSession.java:655)
           at org.modeshape.jcr.JcrSession.node(JcrSession.java:674)
           at
      org.modeshape.jcr.JcrObservationManager$ChangeSetConverter.acceptBasedOnNodeTypeName(JcrObservationManager.java:1115)
           at
      org.modeshape.jcr.JcrObservationManager$ChangeSetConverter.shouldRejectChange(JcrObservationManager.java:1043)
           at
      org.modeshape.jcr.JcrObservationManager$ChangeSetConverter.processChange(JcrObservationManager.java:887)
           at
      org.modeshape.jcr.JcrObservationManager$ChangeSetConverter.convert(JcrObservationManager.java:866)
           at
      org.modeshape.jcr.JcrObservationManager$JcrListenerAdapter.notify(JcrObservationManager.java:374)
           at
      org.modeshape.jcr.bus.RepositoryChangeBus$ChangeSetListenerConsumerAdapter.consume(RepositoryChangeBus.java:161)
           at
      org.modeshape.jcr.bus.RepositoryChangeBus$ChangeSetListenerConsumerAdapter.consume(RepositoryChangeBus.java:155)
           at
      org.modeshape.common.collection.ring.RingBuffer$ConsumerRunner.run(RingBuffer.java:462)
           at
      java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
           at
      java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
           at java.lang.Thread.run(Thread.java:745)
      

      In the second test (catchExceptionTest) we catch exception in the event handler (onEvent);

      Attachments

        Issue Links

          Activity

            People

              hchiorean Horia Chiorean (Inactive)
              gbelov_jira German Belov (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: