We're updating the issue view to help you get more done. 

OsgiWebHookProviderWebHookRegistry has flawed locking logic

Description

The problem is here:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 try { if (!lock.readLock().tryLock(5, TimeUnit.SECONDS)) { throw new IllegalStateException("Could not acquire read lock to WebHooks registrations"); } // do stuff with the lock.... } catch (InterruptedException e) { logger.error("There was an error while reading existing WebHooks events", e); return Collections.emptyList(); } finally { lock.readLock().unlock(); }

The problem is that if the tryLock fails with InterruptedException the unlock call in finally will fail because there is no lock held currently by the thread, so the effort to return an empty list is futile. Below is what happens when the InterruptedException indeed occurs (not the IllegalMonitorStateException thrown from the finally block):

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 2014-08-15 10:23:22,936 ERROR [threadpool:thread-19519] backup_user 622x254040x0 14owtfx 10.10.50.27,127.0.0.1 "POST /mvc/admin/backups HTTP/1.1" c.a.w.p.OsgiWebHookProviderWebHookRegistry There was an error while reading existing WebHooks events java.lang.InterruptedException: null at java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireSharedNanos(AbstractQueuedSynchronizer.java:1325) ~[na:1.7.0_55] at java.util.concurrent.locks.ReentrantReadWriteLock$ReadLock.tryLock(ReentrantReadWriteLock.java:873) ~[na:1.7.0_55] at com.atlassian.webhooks.plugin.OsgiWebHookProviderWebHookRegistry.getWebHooks(OsgiWebHookProviderWebHookRegistry.java:65) [atlassian-webhooks-plugin-1.0.1_1396943630000.jar:na] at com.atlassian.webhooks.plugin.OsgiWebHookProviderWebHookRegistry.getWebHooks(OsgiWebHookProviderWebHookRegistry.java:37) [atlassian-webhooks-plugin-1.0.1_1396943630000.jar:na] at com.atlassian.webhooks.plugin.DelegatingWebHookRegistry$2.apply(DelegatingWebHookRegistry.java:40) [atlassian-webhooks-plugin-1.0.1_1396943630000.jar:na] at com.atlassian.webhooks.plugin.DelegatingWebHookRegistry$2.apply(DelegatingWebHookRegistry.java:36) [atlassian-webhooks-plugin-1.0.1_1396943630000.jar:na] at com.google.common.collect.Iterators$8.next(Iterators.java:812) [guava-11.0.2-atlassian-01.jar:na] at com.google.common.collect.Iterables$3.next(Iterables.java:508) [guava-11.0.2-atlassian-01.jar:na] at com.google.common.collect.Iterables$3.next(Iterables.java:501) [guava-11.0.2-atlassian-01.jar:na] at com.google.common.collect.Iterators$5.hasNext(Iterators.java:544) [guava-11.0.2-atlassian-01.jar:na] at com.atlassian.webhooks.plugin.WebHookEventsProcessor.doOnEvent(WebHookEventsProcessor.java:37) [atlassian-webhooks-plugin-1.0.1_1396943630000.jar:na] at com.atlassian.webhooks.plugin.WebHookEventsProcessor.onEvent(WebHookEventsProcessor.java:32) [atlassian-webhooks-plugin-1.0.1_1396943630000.jar:na] at com.atlassian.event.internal.SingleParameterMethodListenerInvoker.invoke(SingleParameterMethodListenerInvoker.java:36) [atlassian-event-2.3.5.jar:na] at com.atlassian.event.internal.AsynchronousAbleEventDispatcher$1$1.run(AsynchronousAbleEventDispatcher.java:48) [atlassian-event-2.3.5.jar:na] at com.google.common.util.concurrent.MoreExecutors$SameThreadExecutorService.execute(MoreExecutors.java:253) [guava-11.0.2-atlassian-01.jar:na] at com.atlassian.event.internal.AsynchronousAbleEventDispatcher.dispatch(AsynchronousAbleEventDispatcher.java:107) [atlassian-event-2.3.5.jar:na] at com.atlassian.stash.internal.event.LockFreeEventPublisher$Publisher.dispatch(LockFreeEventPublisher.java:201) [stash-platform-3.0.4.jar:na] at com.atlassian.stash.internal.event.LockFreeEventPublisher.publish(LockFreeEventPublisher.java:75) [stash-platform-3.0.4.jar:na] at com.atlassian.stash.internal.event.TransactionAwareEventPublisher.publish(TransactionAwareEventPublisher.java:84) [stash-platform-3.0.4.jar:na] at com.atlassian.stash.internal.maintenance.DefaultMaintenanceModeHelper.unlock(DefaultMaintenanceModeHelper.java:38) [stash-service-impl-3.0.4.jar:na] at com.atlassian.stash.internal.maintenance.MaintenanceModePhase.run(MaintenanceModePhase.java:29) [stash-service-impl-3.0.4.jar:na] at com.atlassian.stash.internal.maintenance.backup.AbstractBackupTask.run(AbstractBackupTask.java:84) [stash-service-impl-3.0.4.jar:na] at com.atlassian.stash.internal.maintenance.DefaultMaintenanceTaskMonitor.run(DefaultMaintenanceTaskMonitor.java:169) [stash-service-impl-3.0.4.jar:na] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) [na:1.7.0_55] at java.util.concurrent.FutureTask.run(FutureTask.java:262) [na:1.7.0_55] at com.atlassian.stash.internal.concurrent.StateTransferringExecutor$StateTransferringRunnable.run(StateTransferringExecutor.java:69) [stash-platform-3.0.4.jar:na] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) [na:1.7.0_55] at java.util.concurrent.FutureTask.run(FutureTask.java:262) [na:1.7.0_55] at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:178) [na:1.7.0_55] at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:292) [na:1.7.0_55] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [na:1.7.0_55] at java.lang.Thread.run(Thread.java:744) [na:1.7.0_55] ... 4 frames trimmed 2014-08-15 10:23:22,941 ERROR [threadpool:thread-19519] backup_user 622x254040x0 14owtfx 10.10.50.27,127.0.0.1 "POST /mvc/admin/backups HTTP/1.1" c.a.e.i.AsynchronousAbleEventDispatcher There was an exception thrown trying to dispatch event [com.atlassian.johnson.event.RemoveEvent[source=com.atlassian.stash.internal.maintenance.DefaultMaintenanceModeHelper@6efe63ec]] from the invoker [SingleParameterMethodListenerInvoker{method=public void com.atlassian.webhooks.plugin.WebHookEventsProcessor.onEvent(java.lang.Object), listener=com.atlassian.webhooks.plugin.WebHookEventsProcessor@1952acf}] java.lang.RuntimeException: attempt to unlock read lock, not locked by current thread at com.atlassian.event.internal.SingleParameterMethodListenerInvoker.invoke(SingleParameterMethodListenerInvoker.java:54) ~[atlassian-event-2.3.5.jar:na] at com.atlassian.event.internal.AsynchronousAbleEventDispatcher$1$1.run(AsynchronousAbleEventDispatcher.java:48) ~[atlassian-event-2.3.5.jar:na] at com.google.common.util.concurrent.MoreExecutors$SameThreadExecutorService.execute(MoreExecutors.java:253) [guava-11.0.2-atlassian-01.jar:na] at com.atlassian.event.internal.AsynchronousAbleEventDispatcher.dispatch(AsynchronousAbleEventDispatcher.java:107) [atlassian-event-2.3.5.jar:na] at com.atlassian.stash.internal.event.LockFreeEventPublisher$Publisher.dispatch(LockFreeEventPublisher.java:201) [stash-platform-3.0.4.jar:na] at com.atlassian.stash.internal.event.LockFreeEventPublisher.publish(LockFreeEventPublisher.java:75) [stash-platform-3.0.4.jar:na] at com.atlassian.stash.internal.event.TransactionAwareEventPublisher.publish(TransactionAwareEventPublisher.java:84) [stash-platform-3.0.4.jar:na] at com.atlassian.stash.internal.maintenance.DefaultMaintenanceModeHelper.unlock(DefaultMaintenanceModeHelper.java:38) [stash-service-impl-3.0.4.jar:na] at com.atlassian.stash.internal.maintenance.MaintenanceModePhase.run(MaintenanceModePhase.java:29) [stash-service-impl-3.0.4.jar:na] at com.atlassian.stash.internal.maintenance.backup.AbstractBackupTask.run(AbstractBackupTask.java:84) [stash-service-impl-3.0.4.jar:na] at com.atlassian.stash.internal.maintenance.DefaultMaintenanceTaskMonitor.run(DefaultMaintenanceTaskMonitor.java:169) [stash-service-impl-3.0.4.jar:na] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) [na:1.7.0_55] at java.util.concurrent.FutureTask.run(FutureTask.java:262) [na:1.7.0_55] at com.atlassian.stash.internal.concurrent.StateTransferringExecutor$StateTransferringRunnable.run(StateTransferringExecutor.java:69) [stash-platform-3.0.4.jar:na] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) [na:1.7.0_55] at java.util.concurrent.FutureTask.run(FutureTask.java:262) [na:1.7.0_55] at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:178) [na:1.7.0_55] at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:292) [na:1.7.0_55] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [na:1.7.0_55] at java.lang.Thread.run(Thread.java:744) [na:1.7.0_55] ... 1 frame trimmed Caused by: java.lang.IllegalMonitorStateException: attempt to unlock read lock, not locked by current thread at java.util.concurrent.locks.ReentrantReadWriteLock$Sync.unmatchedUnlockException(ReentrantReadWriteLock.java:447) ~[na:1.7.0_55] at java.util.concurrent.locks.ReentrantReadWriteLock$Sync.tryReleaseShared(ReentrantReadWriteLock.java:431) ~[na:1.7.0_55] at java.util.concurrent.locks.AbstractQueuedSynchronizer.releaseShared(AbstractQueuedSynchronizer.java:1340) ~[na:1.7.0_55] at java.util.concurrent.locks.ReentrantReadWriteLock$ReadLock.unlock(ReentrantReadWriteLock.java:883) ~[na:1.7.0_55] at com.atlassian.webhooks.plugin.OsgiWebHookProviderWebHookRegistry.getWebHooks(OsgiWebHookProviderWebHookRegistry.java:103) ~[na:na] at com.atlassian.webhooks.plugin.OsgiWebHookProviderWebHookRegistry.getWebHooks(OsgiWebHookProviderWebHookRegistry.java:37) ~[na:na] at com.atlassian.webhooks.plugin.DelegatingWebHookRegistry$2.apply(DelegatingWebHookRegistry.java:40) ~[na:na] at com.atlassian.webhooks.plugin.DelegatingWebHookRegistry$2.apply(DelegatingWebHookRegistry.java:36) ~[na:na] at com.google.common.collect.Iterators$8.next(Iterators.java:812) ~[guava-11.0.2-atlassian-01.jar:na] at com.google.common.collect.Iterables$3.next(Iterables.java:508) ~[guava-11.0.2-atlassian-01.jar:na] at com.google.common.collect.Iterables$3.next(Iterables.java:501) ~[guava-11.0.2-atlassian-01.jar:na] at com.google.common.collect.Iterators$5.hasNext(Iterators.java:544) ~[guava-11.0.2-atlassian-01.jar:na] at com.atlassian.webhooks.plugin.WebHookEventsProcessor.doOnEvent(WebHookEventsProcessor.java:37) ~[na:na] at com.atlassian.webhooks.plugin.WebHookEventsProcessor.onEvent(WebHookEventsProcessor.java:32) ~[na:na] at com.atlassian.event.internal.SingleParameterMethodListenerInvoker.invoke(SingleParameterMethodListenerInvoker.java:36) ~[atlassian-event-2.3.5.jar:na] ... 20 common frames omitted

Environment

None

Testing Notes

None

Status

Assignee

Unassigned

Reporter

Dariusz Kordonski

Labels

Add-on Type

None

Team

None

CC

None

Risk factor

None

QA Kickoff Status

None

QA Demo Status

None

Affects versions

1.0.1
1.0.4

Priority

Major