Search code examples
sessiontomcat7liferay-6deadlockvaadin7

How can I set an attribute in Liferay's APPLICATION_SCOPE whilst inside of a Vaadin request


Some background; I'm running a Vaadin 7 application as a portlet on Liferay 6.2.GA6 running on clustered Tomcat7 instances using DeltaManager.

I'm attempting to set a user-level session attribute in my Vaadin Application that other portlets can view, and react appropriately.

The code below results in a thread deadlock.

'    
PortletSession session = ((WrappedPortletSession)UI.getCurrent().getSesion()).getPortletSession();
session.setAttribute("CURRENT_NOTIFICATION",notificationDTO,PortletSession.APPLICATION_SCOPE);

My resulting abbreviated thread dump...

"http-nio-8081-exec-80" - Thread t@1030
   java.lang.Thread.State: WAITING
    at sun.misc.Unsafe.park(Native Method)
    - waiting to lock <7c3f1e38> (a java.util.concurrent.locks.ReentrantReadWriteLock$NonfairSync) owned by "http-nio-8081-exec-82" t@1036
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:834)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:867)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1197)
    at java.util.concurrent.locks.ReentrantReadWriteLock$WriteLock.lock(ReentrantReadWriteLock.java:945)
    at org.apache.catalina.ha.session.DeltaSession.lock(DeltaSession.java:199)
    at org.apache.catalina.ha.session.DeltaSession.setAttribute(DeltaSession.java:726)
    at org.apache.catalina.ha.session.DeltaSession.setAttribute(DeltaSession.java:711)
    at org.apache.catalina.session.StandardSessionFacade.setAttribute(StandardSessionFacade.java:154)
    at com.liferay.portlet.PortletSessionImpl.setAttribute(PortletSessionImpl.java:188)
    at mypackage.com.view.NotificationEntryView.enter(NotificationEntryView.java:181)


    "http-nio-8081-exec-82" - Thread t@1036
   java.lang.Thread.State: WAITING
    at sun.misc.Unsafe.park(Native Method)
    - waiting to lock <fa6510c> (a java.util.concurrent.locks.ReentrantLock$NonfairSync) owned by "http-nio-8081-exec-80" t@1030
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:834)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:867)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1197)
    at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:214)
    at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:290)
    at com.vaadin.server.VaadinSession.writeObject(VaadinSession.java:1432)
    at sun.reflect.GeneratedMethodAccessor1827.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:988)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1495)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347)
    at org.apache.catalina.ha.session.DeltaRequest$AttributeInfo.writeExternal(DeltaRequest.java:407)
    at org.apache.catalina.ha.session.DeltaRequest.writeExternal(DeltaRequest.java:300)
    at org.apache.catalina.ha.session.DeltaRequest.serialize(DeltaRequest.java:314)
    at org.apache.catalina.ha.session.DeltaManager.serializeDeltaRequest(DeltaManager.java:610)
    at org.apache.catalina.ha.session.DeltaManager.requestCompleted(DeltaManager.java:996)
    - locked <5603aa01> (a org.apache.catalina.ha.session.DeltaRequest)

It appears that the setAttribute call on PorletSession triggers DeltaSession to attempt a lock on the session which Vaadin already (kind-of) holds which deadlocks.

Vaadin suggests using VaadinSession or UI.access(). This hasn't helped.

My next idea is to manually unlock VaadinSession, set the Attribute and then relock the VaadinSession, which seems to be a risky move.

Can anyone recommend a solution?


Solution

  • Well unlocking the VaadinSession before setting the user session attribute appears to have solved the deadlock issue, and re-locking the VaadinSession also seems to work.

    So problem solved somewhat for now.