use of com.sun.ejb.InvocationInfo in project Payara by payara.
the class SafeProperties method addLocalRemoteInvocationInfo.
protected void addLocalRemoteInvocationInfo() throws Exception {
if (isRemote) {
if (hasRemoteHomeView) {
// Process Remote intf
Method[] methods = remoteIntf.getMethods();
for (Method method : methods) {
addInvocationInfo(method, MethodDescriptor.EJB_REMOTE, remoteIntf);
}
// Process EJBHome intf
methods = homeIntf.getMethods();
for (Method method : methods) {
addInvocationInfo(method, MethodDescriptor.EJB_HOME, homeIntf);
}
}
if (hasRemoteBusinessView) {
for (RemoteBusinessIntfInfo next : remoteBusinessIntfInfo.values()) {
// Get methods from generated remote intf but pass
// actual business interface as original interface.
Method[] methods = next.generatedRemoteIntf.getMethods();
for (Method method : methods) {
addInvocationInfo(method, MethodDescriptor.EJB_REMOTE, next.remoteBusinessIntf);
}
}
// Process internal EJB RemoteBusinessHome intf
Method[] methods = remoteBusinessHomeIntf.getMethods();
for (Method method : methods) {
addInvocationInfo(method, MethodDescriptor.EJB_HOME, remoteBusinessHomeIntf);
}
}
}
if (isLocal) {
if (hasLocalHomeView) {
// Process Local interface
Method[] methods = localIntf.getMethods();
for (Method method : methods) {
InvocationInfo info = addInvocationInfo(method, MethodDescriptor.EJB_LOCAL, localIntf);
postProcessInvocationInfo(info);
}
// Process LocalHome interface
methods = localHomeIntf.getMethods();
for (Method method : methods) {
addInvocationInfo(method, MethodDescriptor.EJB_LOCALHOME, localHomeIntf);
}
}
if (hasLocalBusinessView) {
// Process Local Business interfaces
for (Class localBusinessIntf : localBusinessIntfs) {
Method[] methods = localBusinessIntf.getMethods();
for (Method method : methods) {
addInvocationInfo(method, MethodDescriptor.EJB_LOCAL, localBusinessIntf);
}
}
// Process (internal) Local Business Home interface
Method[] methods = localBusinessHomeIntf.getMethods();
for (Method method : methods) {
addInvocationInfo(method, MethodDescriptor.EJB_LOCALHOME, localBusinessHomeIntf);
}
}
if (hasOptionalLocalBusinessView) {
// Process generated Optional Local Business interface
String optClassName = EJBUtils.getGeneratedOptionalInterfaceName(ejbClass.getName());
ejbGeneratedOptionalLocalBusinessIntfClass = optIntfClassLoader.loadClass(optClassName);
Method[] methods = ejbGeneratedOptionalLocalBusinessIntfClass.getMethods();
for (Method method : methods) {
addInvocationInfo(method, MethodDescriptor.EJB_LOCAL, ejbGeneratedOptionalLocalBusinessIntfClass, false, true);
}
// Process generated Optional Local Business interface
Method[] optHomeMethods = ejbOptionalLocalBusinessHomeIntf.getMethods();
for (Method method : optHomeMethods) {
addInvocationInfo(method, MethodDescriptor.EJB_LOCALHOME, ejbOptionalLocalBusinessHomeIntf);
}
}
if (!hasLocalHomeView) {
// Add dummy local business interface remove method so that internal
// container remove operations will work. (needed for internal 299 contract)
addInvocationInfo(this.ejbIntfMethods[EJBLocalObject_remove], MethodDescriptor.EJB_LOCAL, javax.ejb.EJBLocalObject.class);
}
}
}
use of com.sun.ejb.InvocationInfo in project Payara by payara.
the class SafeProperties method createInvocationInfo.
/**
* Create invocation info for one method.
*
* @param originalIntf Leaf interface for the given view. Not set for
* methodIntf == bean.
*/
private final InvocationInfo createInvocationInfo(Method method, int txAttr, boolean flushEnabled, String methodIntf, Class originalIntf) throws EJBException {
InvocationInfo invInfo = new InvocationInfo(method);
invInfo.str_method_sig = EjbMonitoringUtils.stringify(method);
invInfo.ejbName = ejbDescriptor.getName();
invInfo.txAttr = txAttr;
invInfo.methodIntf = methodIntf;
invInfo.isBusinessMethod = isBusinessMethod(method);
invInfo.isCreateHomeFinder = isCreateHomeFinder(method);
invInfo.startsWithCreate = method.getName().startsWith("create");
invInfo.startsWithFind = method.getName().startsWith("find");
invInfo.startsWithRemove = method.getName().startsWith("remove");
invInfo.startsWithFindByPrimaryKey = method.getName().startsWith("findByPrimaryKey");
invInfo.flushEnabled = flushEnabled;
if (methodIntf.equals(MethodDescriptor.EJB_LOCALHOME)) {
if (method.getDeclaringClass() != EJBLocalHome.class) {
setHomeTargetMethodInfo(invInfo, true);
}
} else if (methodIntf.equals(MethodDescriptor.EJB_HOME)) {
if (method.getDeclaringClass() != EJBHome.class) {
setHomeTargetMethodInfo(invInfo, false);
}
} else if (methodIntf.equals(MethodDescriptor.EJB_LOCAL)) {
if (method.getDeclaringClass() != EJBLocalObject.class) {
setEJBObjectTargetMethodInfo(invInfo, true, originalIntf);
}
} else if (methodIntf.equals(MethodDescriptor.EJB_REMOTE)) {
if (method.getDeclaringClass() != EJBObject.class) {
setEJBObjectTargetMethodInfo(invInfo, false, originalIntf);
}
}
setConcurrencyInvInfo(method, methodIntf, invInfo);
if (_logger.isLoggable(Level.FINE)) {
_logger.log(Level.FINE, invInfo.toString());
}
adjustInvocationInfo(invInfo, method, txAttr, flushEnabled, methodIntf, originalIntf);
return invInfo;
}
use of com.sun.ejb.InvocationInfo in project Payara by payara.
the class SafeProperties method addInvocationInfo.
private InvocationInfo addInvocationInfo(Method method, String methodIntf, Class originalIntf, boolean isEjbTimeout, boolean optionalLocalBusView) throws EJBException {
MethodDescriptor md = new MethodDescriptor(method, methodIntf);
boolean flushEnabled = findFlushEnabledAttr(md);
int txAttr = containerTransactionManager.findTxAttr(md);
InvocationInfo info = createInvocationInfo(method, txAttr, flushEnabled, methodIntf, originalIntf);
boolean isHomeIntf = methodIntf.equals(MethodDescriptor.EJB_HOME) || methodIntf.equals(MethodDescriptor.EJB_LOCALHOME);
if (!isHomeIntf) {
Method beanMethod = null;
if (!isEjbTimeout) {
try {
beanMethod = getEJBClass().getMethod(method.getName(), method.getParameterTypes());
} catch (NoSuchMethodException nsmEx) {
// TODO
}
} else {
// For a timeout it is the method
beanMethod = method;
}
if (beanMethod != null) {
// Can't set AroundInvoke/AroundTimeout chains here, but set up some
// state on info object so it can be done right after InterceptorManager
// is initialized.
info.aroundMethod = beanMethod;
info.isEjbTimeout = isEjbTimeout;
}
// Asynchronous method initialization
if (isEligibleForAsync(originalIntf, methodIntf)) {
Method targetMethod = optionalLocalBusView ? beanMethod : method;
boolean isAsync = ((EjbSessionDescriptor) ejbDescriptor).isAsynchronousMethod(targetMethod);
if (isAsync) {
// Check return type
if (optionalLocalBusView && beanMethod != null) {
boolean beanMethodReturnTypeVoid = beanMethod.getReturnType().equals(Void.TYPE);
boolean beanMethodReturnTypeFuture = beanMethod.getReturnType().equals(Future.class);
if (!beanMethodReturnTypeVoid && !beanMethodReturnTypeFuture) {
throw new RuntimeException("Invalid no-interface view asynchronous method '" + beanMethod + "' for bean " + ejbDescriptor.getName() + ". Async method exposed through no-interface view must " + " have return type void or java.lang.concurrent.Future<V>");
}
} else {
// Use actual interface method instead of method from generated interface
Method intfMethod = null;
try {
intfMethod = originalIntf.getMethod(method.getName(), method.getParameterTypes());
} catch (NoSuchMethodException nsmEx) {
throw new RuntimeException("No matching async intf method for method '" + beanMethod + "' on bean " + ejbDescriptor.getName());
}
if (beanMethod == null) {
throw new RuntimeException("No matching bean class method for async method '" + intfMethod + "' on bean " + ejbDescriptor.getName());
}
boolean beanMethodReturnTypeVoid = beanMethod.getReturnType().equals(Void.TYPE);
boolean beanMethodReturnTypeFuture = beanMethod.getReturnType().equals(Future.class);
boolean intfMethodReturnTypeVoid = intfMethod.getReturnType().equals(Void.TYPE);
boolean intfMethodReturnTypeFuture = intfMethod.getReturnType().equals(Future.class);
boolean bothVoid = intfMethodReturnTypeVoid && beanMethodReturnTypeVoid;
boolean bothFuture = intfMethodReturnTypeFuture && beanMethodReturnTypeFuture;
if (!bothVoid && !bothFuture) {
throw new RuntimeException(//
"Invalid asynchronous bean class / interface " + "method signatures for bean " + //
ejbDescriptor.getName() + ". beanMethod = '" + beanMethod + "' , interface method = '" + intfMethod + "'");
}
}
info.setIsAsynchronous(true);
}
}
}
if (methodIntf.equals(MethodDescriptor.EJB_WEB_SERVICE)) {
webServiceInvocationInfoMap.put(method, info);
} else {
invocationInfoMap.put(method, info);
}
return info;
}
use of com.sun.ejb.InvocationInfo 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;
}
use of com.sun.ejb.InvocationInfo in project Payara by payara.
the class EJBHomeInvocationHandler method invoke.
/**
* Called by EJBHome proxy.
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
ClassLoader originalClassLoader = null;
// if method signature has 0 arguments.
try {
((BaseContainer) getContainer()).onEnteringContainer();
if (Thread.currentThread().getContextClassLoader() != getContainer().getClassLoader()) {
originalClassLoader = Utility.setContextClassLoader(getContainer().getClassLoader());
}
Class methodClass = method.getDeclaringClass();
if (methodClass == java.lang.Object.class) {
return InvocationHandlerUtil.invokeJavaObjectMethod(this, method, args);
} else if (invokeSpecialEJBHomeMethod(method, methodClass, args)) {
return null;
}
// Use optimized version of get that takes param count as an
// argument.
InvocationInfo invInfo = (InvocationInfo) invocationInfoMap_.get(method, ((args != null) ? args.length : 0));
if (invInfo == null) {
throw new RemoteException("Unknown Home interface method :" + method);
} else if ((methodClass == javax.ejb.EJBHome.class) || invInfo.ejbIntfOverride) {
return invokeEJBHomeMethod(method.getName(), args);
} else if (GenericEJBHome.class.isAssignableFrom(methodClass)) {
if (method.getName().equals("create")) {
// This is an internal creation request through the EJB 3.0
// client view, so just create an business object and return it
EJBObjectImpl busObjectImpl = createRemoteBusinessObjectImpl();
return busObjectImpl.getStub((String) args[0]);
} else {
EjbAsyncInvocationManager asyncManager = ((EjbContainerUtilImpl) ejbContainerUtil).getEjbAsyncInvocationManager();
Long asyncTaskID = (Long) args[0];
RemoteAsyncResult asyncResult = null;
if (method.getName().equals("cancel")) {
asyncResult = asyncManager.remoteCancel(asyncTaskID);
} else if (method.getName().equals("get")) {
asyncResult = asyncManager.remoteGet(asyncTaskID);
} else if (method.getName().equals("isDone")) {
asyncResult = asyncManager.remoteIsDone(asyncTaskID);
} else if (method.getName().equals("getWithTimeout")) {
Long timeout = (Long) args[1];
TimeUnit unit = TimeUnit.valueOf((String) args[2]);
asyncResult = asyncManager.remoteGetWithTimeout(asyncTaskID, timeout, unit);
}
return asyncResult;
}
}
// Process finder, create method, or home method.
EJBObjectImpl ejbObjectImpl = null;
Object returnValue = null;
if (invInfo.startsWithCreate) {
ejbObjectImpl = createEJBObjectImpl();
if (ejbObjectImpl != null) {
// Entity beans are created differently
returnValue = ejbObjectImpl.getStub();
}
}
if (!isStatelessSession_) {
if (invInfo.targetMethod1 == null) {
_logger.log(Level.SEVERE, "ejb.bean_class_method_not_found", new Object[] { invInfo.ejbName, "Home", invInfo.method.toString() });
// in exception use message without ID
String errorMsg = localStrings.getLocalString("ejb.bean_class_method_not_found", "", new Object[] { invInfo.ejbName, "Home", invInfo.method.toString() });
throw new RemoteException(errorMsg);
}
EjbInvocation inv = ((BaseContainer) getContainer()).createEjbInvocation();
inv.isRemote = true;
inv.method = method;
inv.isHome = true;
inv.clientInterface = homeIntfClass_;
// Set cached invocation params. This will save
// additional lookups in BaseContainer.
inv.transactionAttribute = invInfo.txAttr;
inv.invocationInfo = invInfo;
if (ejbObjectImpl != null && invInfo.startsWithCreate) {
inv.ejbObject = (EJBLocalRemoteObject) ejbObjectImpl;
}
BaseContainer container = (BaseContainer) getContainer();
try {
container.preInvoke(inv);
if (invInfo.startsWithCreate) {
Object ejbCreateReturnValue = invokeTargetBeanMethod(container, invInfo.targetMethod1, inv, inv.ejb, args);
postCreate(container, inv, invInfo, ejbCreateReturnValue, args);
if (inv.ejbObject != null) {
returnValue = ((EJBObjectImpl) inv.ejbObject).getStub();
}
} else if (invInfo.startsWithFindByPrimaryKey) {
returnValue = container.invokeFindByPrimaryKey(invInfo.targetMethod1, inv, args);
} else if (invInfo.startsWithFind) {
Object pKeys = invokeTargetBeanMethod(container, invInfo.targetMethod1, inv, inv.ejb, args);
returnValue = container.postFind(inv, pKeys, null);
} else {
returnValue = invokeTargetBeanMethod(container, invInfo.targetMethod1, inv, inv.ejb, args);
}
} catch (InvocationTargetException ite) {
inv.exception = ite.getCause();
} catch (Throwable c) {
inv.exception = c;
} finally {
container.postInvoke(inv);
}
if (inv.exception != null) {
InvocationHandlerUtil.throwRemoteException(inv.exception, method.getExceptionTypes());
}
}
return returnValue;
} finally {
if (originalClassLoader != null) {
Utility.setContextClassLoader(originalClassLoader);
}
((BaseContainer) getContainer()).onLeavingContainer();
}
}
Aggregations