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();
}
}
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();
}
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;
}
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);
}
}
}
Aggregations