Search in sources :

Example 1 with IllegalLoopbackException

use of javax.ejb.IllegalLoopbackException in project wildfly by wildfly.

the class EJBReadWriteLockTest method testIllegalLoopBack.

/**
     * Test that a {@link javax.ejb.IllegalLoopbackException} is thrown when the thread owning a read lock
     * tries to obtain a write lock
     *
     * @throws Exception
     */
@Test
public void testIllegalLoopBack() throws Exception {
    // get a read lock
    Lock readLock = this.ejbReadWriteLock.readLock();
    // lock it!
    readLock.lock();
    // now get a write lock and try to lock it (should fail with IllegalLoopBack)
    Lock writeLock = this.ejbReadWriteLock.writeLock();
    try {
        writeLock.lock();
        // unlock the (unexpected obtained lock) and then fail the testcase
        writeLock.unlock();
        Assert.fail("Unexpected acquired write lock");
    } catch (IllegalLoopbackException ilbe) {
    // expected
    } finally {
        // unlock the write lock
        readLock.unlock();
    }
}
Also used : IllegalLoopbackException(javax.ejb.IllegalLoopbackException) Lock(java.util.concurrent.locks.Lock) Test(org.junit.Test)

Example 2 with IllegalLoopbackException

use of javax.ejb.IllegalLoopbackException in project wildfly by wildfly.

the class SingletonReentrantTestCase method testReadCall.

@Test
public void testReadCall() throws Exception {
    final SingletonBean singleton = lookup(SingletonBean.class.getSimpleName(), SingletonBean.class);
    singleton.resetCalled();
    ExecutorService pool = Executors.newSingleThreadExecutor();
    ExecutorService pool2 = Executors.newSingleThreadExecutor();
    final CountDownLatch oneWaiting = new CountDownLatch(1);
    final CountDownLatch twoWaiting = new CountDownLatch(1);
    Future<?> firstOne = pool.submit(new SingletonCallableRead(oneWaiting));
    Future<?> otherOne = pool2.submit(new SingletonCallableRead(twoWaiting));
    // first one could proceed - other one has to wait for end of work of first one
    oneWaiting.countDown();
    Assert.assertEquals(new Integer(1), firstOne.get(WAITING_S, TimeUnit.SECONDS));
    twoWaiting.countDown();
    Assert.assertEquals(new Integer(2), otherOne.get(WAITING_S, TimeUnit.SECONDS));
    // Expecting exception - calling reentrant write method with read lock
    try {
        firstOne = pool.submit(new SingletonCallableRead(null));
        firstOne.get();
        Assert.fail("Supposing " + IllegalLoopbackException.class.getName());
    } catch (IllegalLoopbackException ile) {
    // OK - supposed
    } catch (Exception e) {
        if (!hasCause(e, IllegalLoopbackException.class)) {
            Assert.fail("Supposed caused exception is " + IllegalLoopbackException.class.getName());
        }
    }
    pool.shutdown();
    pool2.shutdown();
}
Also used : IllegalLoopbackException(javax.ejb.IllegalLoopbackException) ExecutorService(java.util.concurrent.ExecutorService) CountDownLatch(java.util.concurrent.CountDownLatch) NamingException(javax.naming.NamingException) IllegalLoopbackException(javax.ejb.IllegalLoopbackException) Test(org.junit.Test)

Example 3 with IllegalLoopbackException

use of javax.ejb.IllegalLoopbackException in project Payara by payara.

the class CMCSingletonContainer method _getContext.

/*
     * Findbugs complains that the lock acquired in this method is not
     *  unlocked on all paths in this method.
     *
     * Even though the method doesn't unlock the (possibly) acquired
     * lock, the lock is guaranteed to be unlocked in releaseContext()
     * even in the presence of (both checked and unchecked) exceptions.
     *
     * The general pattern used by various parts of the EJB container code is:
     *
     * try {
     *      container.preInvoke(inv);
     *      returnValue = container.intercept(inv);
     * } catch (Exception1 e1) {
     *      ...
     * } catch (Exception2 e2) {
     *      ...
     * } finally {
     *      container.postInvoke();
     * }
     *
     * Thus, it is clear that, BaseContainer.postInvoke() which in turn
     * calls releaseContext() will be called if container.preInvoke()
     * is called. This ensures that CMCSingletonContainer (this class)
     * releases the lock acquired by _getContext().
     *
     * Also, note that the above works even for loopback methods as
     * container.preInvoke() and container,postInvoke() will be called
     * before every bean method.
     *
     */
@Override
protected ComponentContext _getContext(EjbInvocation inv) {
    super._getContext(inv);
    InvocationInfo invInfo = inv.invocationInfo;
    MethodLockInfo lockInfo = (invInfo.methodLockInfo == null) ? defaultMethodLockInfo : invInfo.methodLockInfo;
    Lock theLock;
    if (lockInfo.isDistributed()) {
        theLock = clusteredLookup.getDistributedLock();
    } else {
        theLock = lockInfo.isReadLockedMethod() ? readLock : writeLock;
    }
    if ((rwLock.getReadHoldCount() > 0) && (!rwLock.isWriteLockedByCurrentThread())) {
        if (lockInfo.isWriteLockedMethod()) {
            throw new IllegalLoopbackException("Illegal Reentrant Access : Attempt to make " + "a loopback call on a Write Lock method '" + invInfo.targetMethod1 + "' while a Read lock is already held");
        }
    }
    /*
         * Please see comment at the beginning of the method.
         * Even though the method doesn't unlock the (possibly) acquired
         * lock, the lock is guaranteed to be unlocked in releaseContext()
         * even if exceptions were thrown in _getContext()
         */
    if (!lockInfo.hasTimeout() || ((lockInfo.hasTimeout() && (lockInfo.getTimeout() == BLOCK_INDEFINITELY)))) {
        theLock.lock();
    } else {
        try {
            boolean lockStatus = theLock.tryLock(lockInfo.getTimeout(), lockInfo.getTimeUnit());
            if (!lockStatus) {
                String msg = "Couldn't acquire a lock within " + lockInfo.getTimeout() + " " + lockInfo.getTimeUnit();
                if (lockInfo.getTimeout() == NO_BLOCKING) {
                    throw new ConcurrentAccessException(msg);
                } else {
                    throw new ConcurrentAccessTimeoutException(msg);
                }
            }
        } catch (InterruptedException inEx) {
            String msg = "Couldn't acquire a lock within " + lockInfo.getTimeout() + " " + lockInfo.getTimeUnit();
            ConcurrentAccessException cae = (lockInfo.getTimeout() == NO_BLOCKING) ? new ConcurrentAccessException(msg) : new ConcurrentAccessTimeoutException(msg);
            cae.initCause(inEx);
            throw cae;
        }
    }
    // Now that we have acquired the lock, remember it
    inv.setCMCLock(theLock);
    // Now that we have the lock return the singletonCtx
    return singletonCtx;
}
Also used : IllegalLoopbackException(javax.ejb.IllegalLoopbackException) InvocationInfo(com.sun.ejb.InvocationInfo) ConcurrentAccessException(javax.ejb.ConcurrentAccessException) ConcurrentAccessTimeoutException(javax.ejb.ConcurrentAccessTimeoutException) MethodLockInfo(com.sun.ejb.MethodLockInfo) Lock(java.util.concurrent.locks.Lock) ReentrantReadWriteLock(java.util.concurrent.locks.ReentrantReadWriteLock)

Example 4 with IllegalLoopbackException

use of javax.ejb.IllegalLoopbackException in project Payara by payara.

the class AsynchronousTask method handleConcurrentInvocation.

private void handleConcurrentInvocation(boolean allowSerializedAccess, EjbInvocation inv, SessionContextImpl sc, Object sessionKey) {
    if (_logger.isLoggable(TRACE_LEVEL)) {
        logTraceInfo(inv, sessionKey, "Another invocation in progress");
    }
    if (allowSerializedAccess) {
        // What is this exactly protecting against?
        if (sc.getStatefulWriteLock().getHoldCount() > 1) {
            String calleeEjbName = inv.invocationInfo.ejbName;
            String callerEjbName = getCallerEjbName();
            if (!calleeEjbName.equals(callerEjbName)) {
                throw new IllegalLoopbackException("Illegal Reentrant Access : Attempt to make " + "a loopback call on method '" + inv.beanMethod + " for stateful session bean " + ejbDescriptor.getName());
            }
        }
    } else {
        String errMsg = "Concurrent Access attempt on method " + inv.beanMethod + " of SessionBean " + ejbDescriptor.getName() + " is prohibited.  SFSB instance is executing another request. " + "[session-key: " + sessionKey + "]";
        ConcurrentAccessException conEx = new ConcurrentAccessException(errMsg);
        if (inv.isBusinessInterface) {
            throw conEx;
        } else {
            // throw an exception (EJB2.0 section 7.5.6).
            throw new EJBException(conEx);
        }
    }
}
Also used : IllegalLoopbackException(javax.ejb.IllegalLoopbackException) ConcurrentAccessException(javax.ejb.ConcurrentAccessException) EJBException(javax.ejb.EJBException)

Aggregations

IllegalLoopbackException (javax.ejb.IllegalLoopbackException)4 Lock (java.util.concurrent.locks.Lock)2 ConcurrentAccessException (javax.ejb.ConcurrentAccessException)2 Test (org.junit.Test)2 InvocationInfo (com.sun.ejb.InvocationInfo)1 MethodLockInfo (com.sun.ejb.MethodLockInfo)1 CountDownLatch (java.util.concurrent.CountDownLatch)1 ExecutorService (java.util.concurrent.ExecutorService)1 ReentrantReadWriteLock (java.util.concurrent.locks.ReentrantReadWriteLock)1 ConcurrentAccessTimeoutException (javax.ejb.ConcurrentAccessTimeoutException)1 EJBException (javax.ejb.EJBException)1 NamingException (javax.naming.NamingException)1