Search in sources :

Example 1 with InvocationInfo

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);
        }
    }
}
Also used : InvocationInfo(com.sun.ejb.InvocationInfo) Method(java.lang.reflect.Method) javax.ejb(javax.ejb)

Example 2 with InvocationInfo

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;
}
Also used : InvocationInfo(com.sun.ejb.InvocationInfo)

Example 3 with InvocationInfo

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;
}
Also used : InvocationInfo(com.sun.ejb.InvocationInfo) Method(java.lang.reflect.Method) MethodDescriptor(com.sun.enterprise.deployment.MethodDescriptor) EjbSessionDescriptor(org.glassfish.ejb.deployment.descriptor.EjbSessionDescriptor) WebServiceEndpoint(com.sun.enterprise.deployment.WebServiceEndpoint)

Example 4 with InvocationInfo

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;
}
Also used : IllegalLoopbackException(javax.ejb.IllegalLoopbackException) InvocationInfo(com.sun.ejb.InvocationInfo) FencedLock(com.hazelcast.cp.lock.FencedLock) ConcurrentAccessException(javax.ejb.ConcurrentAccessException) ConcurrentAccessTimeoutException(javax.ejb.ConcurrentAccessTimeoutException) MethodLockInfo(com.sun.ejb.MethodLockInfo) FencedLock(com.hazelcast.cp.lock.FencedLock) ReentrantReadWriteLock(java.util.concurrent.locks.ReentrantReadWriteLock) Lock(java.util.concurrent.locks.Lock)

Example 5 with InvocationInfo

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();
    }
}
Also used : InvocationInfo(com.sun.ejb.InvocationInfo) EJBHome(javax.ejb.EJBHome) InvocationTargetException(java.lang.reflect.InvocationTargetException) EjbInvocation(com.sun.ejb.EjbInvocation) TimeUnit(java.util.concurrent.TimeUnit) RemoteException(java.rmi.RemoteException)

Aggregations

InvocationInfo (com.sun.ejb.InvocationInfo)15 InvocationTargetException (java.lang.reflect.InvocationTargetException)5 EjbInvocation (com.sun.ejb.EjbInvocation)4 RemoteException (java.rmi.RemoteException)4 EJBException (javax.ejb.EJBException)4 JavaEETransaction (com.sun.enterprise.transaction.api.JavaEETransaction)3 SystemException (javax.transaction.SystemException)3 Transaction (javax.transaction.Transaction)3 ComponentContext (com.sun.ejb.ComponentContext)2 IndirectlySerializable (com.sun.enterprise.container.common.spi.util.IndirectlySerializable)2 MethodDescriptor (com.sun.enterprise.deployment.MethodDescriptor)2 Method (java.lang.reflect.Method)2 ConcurrentAccessException (javax.ejb.ConcurrentAccessException)2 ConcurrentAccessTimeoutException (javax.ejb.ConcurrentAccessTimeoutException)2 IllegalLoopbackException (javax.ejb.IllegalLoopbackException)2 EjbRemovalInfo (org.glassfish.ejb.deployment.descriptor.EjbRemovalInfo)2 FencedLock (com.hazelcast.cp.lock.FencedLock)1 MethodLockInfo (com.sun.ejb.MethodLockInfo)1 BeanStateSynchronization (com.sun.ejb.spi.container.BeanStateSynchronization)1 WebServiceEndpoint (com.sun.enterprise.deployment.WebServiceEndpoint)1