use of javax.ejb.ConcurrentAccessTimeoutException in project wildfly by wildfly.
the class NonPooledEJBComponentInstanceAssociatingInterceptor method processInvocation.
@Override
public Object processInvocation(InterceptorContext context) throws Exception {
final EJBComponent component = getComponent(context, EJBComponent.class);
// create the instance
final ComponentInstance componentInstance = component.createInstance();
context.putPrivateData(ComponentInstance.class, componentInstance);
// if this is set to true we do not invoke instance.destroy
// as we are not allowed to invoke pre-destroy callbacks
boolean discard = false;
try {
return context.proceed();
} catch (Exception ex) {
final EJBComponent ejbComponent = component;
// Detect app exception
if (ejbComponent.getApplicationException(ex.getClass(), context.getMethod()) != null) {
// it's an application exception, just throw it back.
throw ex;
}
if (ex instanceof ConcurrentAccessTimeoutException || ex instanceof ConcurrentAccessException) {
throw ex;
}
if (ex instanceof RuntimeException || ex instanceof RemoteException) {
discard = true;
}
throw ex;
} catch (final Error e) {
discard = true;
throw e;
} catch (final Throwable t) {
discard = true;
throw new RuntimeException(t);
} finally {
// destroy the instance
if (!discard) {
componentInstance.destroy();
}
}
}
use of javax.ejb.ConcurrentAccessTimeoutException in project wildfly by wildfly.
the class PooledInstanceInterceptor method processInvocation.
@Override
public Object processInvocation(InterceptorContext context) throws Exception {
PooledComponent<ComponentInstance> component = (PooledComponent<ComponentInstance>) getComponent(context, EJBComponent.class);
ComponentInstance instance = component.getPool().get();
context.putPrivateData(ComponentInstance.class, instance);
boolean discarded = false;
try {
return context.proceed();
} catch (Exception ex) {
final EJBComponent ejbComponent = (EJBComponent) component;
// Detect app exception
if (ejbComponent.getApplicationException(ex.getClass(), context.getMethod()) != null) {
// it's an application exception, just throw it back.
throw ex;
}
if (ex instanceof ConcurrentAccessTimeoutException || ex instanceof ConcurrentAccessException) {
throw ex;
}
if (ex instanceof RuntimeException || ex instanceof RemoteException) {
discarded = true;
component.getPool().discard(instance);
}
throw ex;
} catch (final Error e) {
discarded = true;
component.getPool().discard(instance);
throw e;
} catch (final Throwable t) {
discarded = true;
component.getPool().discard(instance);
throw new RuntimeException(t);
} finally {
if (!discarded) {
component.getPool().release(instance);
}
}
}
use of javax.ejb.ConcurrentAccessTimeoutException in project tomee by apache.
the class FullPoolFailoverTest method testStatelessBeanTimeout.
public void testStatelessBeanTimeout() throws Exception {
setup(10, 20);
Client.addRetryCondition(ConcurrentAccessTimeoutException.class);
resume = new CountDownLatch(1);
paused = new CountingLatch(10);
// Do a business method...
final Runnable r = new Runnable() {
public void run() {
counter.hit();
}
};
hold.add(red);
for (int i = 0; i < 10; i++) {
Thread t = new Thread(r);
t.start();
}
// Wait for the beans to reach the start line
try {
if (!paused.await(3000, TimeUnit.MILLISECONDS)) {
System.out.println();
}
} catch (final Throwable t) {
System.out.println();
}
assertTrue("expected 10 invocations", paused.await(3000, TimeUnit.MILLISECONDS));
assertEquals(10, CounterBean.instances.get());
assertEquals(10, hits.size());
final List<URI> expected = new ArrayList<URI>();
for (int i = 0; i < 10; i++) {
expected.add(red);
}
assertEquals(expected, hits);
// This one should failover to the blue server
try {
counter.hit();
fail("Expected ConcurrentAccessTimeoutException");
} catch (ConcurrentAccessTimeoutException e) {
// both "red" and "blue" servers are technically using the
// same stateless session bean pool, which is fully busy
// but ... this exception should have come from the "blue" server
}
// one more hit on red that should have failed over to blue
expected.add(red);
expected.add(blue);
assertEquals(expected, hits);
// then it should fail back to red
try {
counter.hit();
fail("Expected ConcurrentAccessTimeoutException");
} catch (ConcurrentAccessTimeoutException e) {
}
expected.add(blue);
expected.add(red);
assertEquals(expected, hits);
// go
resume.countDown();
}
use of javax.ejb.ConcurrentAccessTimeoutException in project tomee by apache.
the class StatefulContainer method obtainInstance.
@SuppressWarnings("LockAcquiredButNotSafelyReleased")
private Instance obtainInstance(final Object primaryKey, final ThreadContext callContext, final Method callMethod, final boolean checkOutIfNecessary) throws OpenEJBException {
if (primaryKey == null) {
throw new SystemException(new NullPointerException("Cannot obtain an instance of the stateful session bean with a null session id"));
}
final Transaction currentTransaction = getTransaction(callContext);
// Find the instance
Instance instance;
synchronized (this) {
instance = checkedOutInstances.get(primaryKey);
if (instance == null) {
// no need to check for extended persistence contexts it shouldn't happen
try {
instance = cache.checkOut(primaryKey, checkOutIfNecessary);
} catch (final OpenEJBException e) {
throw e;
} catch (final Exception e) {
throw new SystemException("Unexpected load exception", e);
}
// Did we find the instance?
if (instance == null) {
throw new InvalidateReferenceException(new NoSuchObjectException("Not Found"));
}
// remember instance until it is returned to the cache
checkedOutInstances.put(primaryKey, instance);
}
}
final Duration accessTimeout = getAccessTimeout(instance.beanContext, callMethod);
final LockFactory.StatefulLock currLock = instance.getLock();
final boolean lockAcquired;
if (accessTimeout == null || accessTimeout.getTime() < 0) {
// wait indefinitely for a lock
currLock.lock();
lockAcquired = true;
} else if (accessTimeout.getTime() == 0) {
// concurrent calls are not allowed, lock only once
lockAcquired = currLock.tryLock();
} else {
// try to get a lock within the specified period.
try {
lockAcquired = currLock.tryLock(accessTimeout.getTime(), accessTimeout.getUnit());
} catch (final InterruptedException e) {
throw new ApplicationException("Unable to get lock.", e);
}
}
// Did we acquire the lock to the current execution?
if (!lockAcquired) {
throw new ApplicationException(new ConcurrentAccessTimeoutException("Unable to get lock."));
}
if (instance.getTransaction() != null) {
if (!instance.getTransaction().equals(currentTransaction) && !instance.getLock().tryLock()) {
throw new ApplicationException(new RemoteException("Instance is in a transaction and cannot be invoked outside that transaction. See EJB 3.0 Section 4.4.4"));
}
} else {
instance.setTransaction(currentTransaction);
}
// Mark the instance in use so we can detect reentrant calls
instance.setInUse(true);
return instance;
}
use of javax.ejb.ConcurrentAccessTimeoutException 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()) {
if (_logger.isLoggable(Level.FINE)) {
// log all lock operations
theLock = (Lock) Proxy.newProxyInstance(loader, new Class<?>[] { Lock.class }, (proxy, method, args) -> {
FencedLock fencedLock = clusteredLookup.getDistributedLock();
_logger.log(Level.FINE, "DistributedLock, about to call {0}, Locked: {1}, Locked by Us: {2}, thread ID {3}", new Object[] { method.getName(), fencedLock.isLocked(), fencedLock.isLockedByCurrentThread(), Thread.currentThread().getId() });
Object rv = method.invoke(fencedLock, args);
_logger.log(Level.FINE, "DistributedLock, after to call {0}, Locked: {1}, Locked by Us: {2}, thread ID {3}", new Object[] { method.getName(), fencedLock.isLocked(), fencedLock.isLockedByCurrentThread(), Thread.currentThread().getId() });
return rv;
});
} else {
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;
}
Aggregations