@Override public void afterPropertiesSet() throws NamingException { super.afterPropertiesSet(); Class<?> ifc = getServiceInterface(); Assert.notNull(ifc, "Property 'serviceInterface' is required"); this.serviceProxy = new ProxyFactory(ifc, this).getProxy(this.beanClassLoader); }
return doInvoke(invocation, (RmiInvocationHandler) stub); throw convertRmiAccessException(ex, invocation.getMethod()); "] failed in RMI service [" + getJndiName() + "]", ex); Throwable targetEx = ex.getTargetException(); if (targetEx instanceof RemoteException) { throw convertRmiAccessException((RemoteException) targetEx, invocation.getMethod());
/** * Apply the given AOP method invocation to the given {@link RmiInvocationHandler}. * <p>The default implementation delegates to {@link #createRemoteInvocation}. * @param methodInvocation the current AOP method invocation * @param invocationHandler the RmiInvocationHandler to apply the invocation to * @return the invocation result * @throws RemoteException in case of communication errors * @throws NoSuchMethodException if the method name could not be resolved * @throws IllegalAccessException if the method could not be accessed * @throws InvocationTargetException if the method invocation resulted in an exception * @see org.springframework.remoting.support.RemoteInvocation */ protected Object doInvoke(MethodInvocation methodInvocation, RmiInvocationHandler invocationHandler) throws RemoteException, NoSuchMethodException, IllegalAccessException, InvocationTargetException { if (AopUtils.isToStringMethod(methodInvocation.getMethod())) { return "RMI invoker proxy for service URL [" + getJndiName() + "]"; } return invocationHandler.invoke(createRemoteInvocation(methodInvocation)); }
/** * Convert the given RMI RemoteException that happened during remote access * to Spring's RemoteAccessException if the method signature does not declare * RemoteException. Else, return the original RemoteException. * @param method the invoked method * @param ex the RemoteException that happened * @return the exception to be thrown to the caller */ private Exception convertRmiAccessException(RemoteException ex, Method method) { return RmiClientInterceptorUtils.convertRmiAccessException(method, ex, isConnectFailure(ex), getJndiName()); }
/** * Refresh the RMI stub and retry the given invocation. * Called by invoke on connect failure. * @param invocation the AOP method invocation * @return the invocation result, if any * @throws Throwable in case of invocation failure * @see #invoke */ @Nullable protected Object refreshAndRetry(MethodInvocation invocation) throws Throwable { Object freshStub; synchronized (this.stubMonitor) { this.cachedStub = null; freshStub = lookupStub(); if (this.cacheStub) { this.cachedStub = freshStub; } } return doInvoke(invocation, freshStub); }
/** * Fetches the RMI stub on startup, if necessary. * @throws RemoteLookupFailureException if RMI stub creation failed * @see #setLookupStubOnStartup * @see #lookupStub */ public void prepare() throws RemoteLookupFailureException { // Cache RMI stub on initialization? if (this.lookupStubOnStartup) { Object remoteObj = lookupStub(); if (logger.isDebugEnabled()) { if (remoteObj instanceof RmiInvocationHandler) { logger.debug("JNDI RMI object [" + getJndiName() + "] is an RMI invoker"); } else if (getServiceInterface() != null) { boolean isImpl = getServiceInterface().isInstance(remoteObj); logger.debug("Using service interface [" + getServiceInterface().getName() + "] for JNDI RMI object [" + getJndiName() + "] - " + (!isImpl ? "not " : "") + "directly implemented"); } } if (this.cacheStub) { this.cachedStub = remoteObj; } } }
Object stub; try { stub = getStub(); throw new RemoteLookupFailureException("JNDI lookup for RMI service [" + getJndiName() + "] failed", ex); Context ctx = (this.exposeAccessContext ? getJndiTemplate().getContext() : null); try { return doInvoke(invocation, stub); return handleRemoteConnectFailure(invocation, ex); if (isConnectFailure(ex)) { return handleRemoteConnectFailure(invocation, ex); getJndiTemplate().releaseContext(ctx);
/** * Create the RMI stub, typically by looking it up. * <p>Called on interceptor initialization if "cacheStub" is "true"; * else called for each invocation by {@link #getStub()}. * <p>The default implementation retrieves the service from the * JNDI environment. This can be overridden in subclasses. * @return the RMI stub to store in this interceptor * @throws RemoteLookupFailureException if RMI stub creation failed * @see #setCacheStub * @see #lookup */ protected Object lookupStub() throws RemoteLookupFailureException { try { return lookup(); } catch (NamingException ex) { throw new RemoteLookupFailureException("JNDI lookup for RMI service [" + getJndiName() + "] failed", ex); } }
/** * Refresh the stub and retry the remote invocation if necessary. * <p>If not configured to refresh on connect failure, this method * simply rethrows the original exception. * @param invocation the invocation that failed * @param ex the exception raised on remote invocation * @return the result value of the new invocation, if succeeded * @throws Throwable an exception raised by the new invocation, if failed too. */ private Object handleRemoteConnectFailure(MethodInvocation invocation, Exception ex) throws Throwable { if (this.refreshStubOnConnectFailure) { if (logger.isDebugEnabled()) { logger.debug("Could not connect to RMI service [" + getJndiName() + "] - retrying", ex); } else if (logger.isInfoEnabled()) { logger.info("Could not connect to RMI service [" + getJndiName() + "] - retrying"); } return refreshAndRetry(invocation); } else { throw ex; } }
/** * Create a new RemoteInvocation object for the given AOP method invocation. * <p>The default implementation delegates to the configured * {@link #setRemoteInvocationFactory RemoteInvocationFactory}. * This can be overridden in subclasses in order to provide custom RemoteInvocation * subclasses, containing additional invocation parameters (e.g. user credentials). * <p>Note that it is preferable to build a custom RemoteInvocationFactory * as a reusable strategy, instead of overriding this method. * @param methodInvocation the current AOP method invocation * @return the RemoteInvocation object * @see RemoteInvocationFactory#createRemoteInvocation */ protected RemoteInvocation createRemoteInvocation(MethodInvocation methodInvocation) { return getRemoteInvocationFactory().createRemoteInvocation(methodInvocation); }
Object stub; try { stub = getStub(); throw new RemoteLookupFailureException("JNDI lookup for RMI service [" + getJndiName() + "] failed", ex); Context ctx = (this.exposeAccessContext ? getJndiTemplate().getContext() : null); try { return doInvoke(invocation, stub); return handleRemoteConnectFailure(invocation, ex); if (isConnectFailure(ex)) { return handleRemoteConnectFailure(invocation, ex); getJndiTemplate().releaseContext(ctx);
/** * Fetches the RMI stub on startup, if necessary. * @throws RemoteLookupFailureException if RMI stub creation failed * @see #setLookupStubOnStartup * @see #lookupStub */ public void prepare() throws RemoteLookupFailureException { // Cache RMI stub on initialization? if (this.lookupStubOnStartup) { Object remoteObj = lookupStub(); if (logger.isDebugEnabled()) { if (remoteObj instanceof RmiInvocationHandler) { logger.debug("JNDI RMI object [" + getJndiName() + "] is an RMI invoker"); } else if (getServiceInterface() != null) { boolean isImpl = getServiceInterface().isInstance(remoteObj); logger.debug("Using service interface [" + getServiceInterface().getName() + "] for JNDI RMI object [" + getJndiName() + "] - " + (!isImpl ? "not " : "") + "directly implemented"); } } if (this.cacheStub) { this.cachedStub = remoteObj; } } }
/** * Convert the given RMI RemoteException that happened during remote access * to Spring's RemoteAccessException if the method signature does not declare * RemoteException. Else, return the original RemoteException. * @param method the invoked method * @param ex the RemoteException that happened * @return the exception to be thrown to the caller */ private Exception convertRmiAccessException(RemoteException ex, Method method) { return RmiClientInterceptorUtils.convertRmiAccessException(method, ex, isConnectFailure(ex), getJndiName()); }
/** * Create the RMI stub, typically by looking it up. * <p>Called on interceptor initialization if "cacheStub" is "true"; * else called for each invocation by {@link #getStub()}. * <p>The default implementation retrieves the service from the * JNDI environment. This can be overridden in subclasses. * @return the RMI stub to store in this interceptor * @throws RemoteLookupFailureException if RMI stub creation failed * @see #setCacheStub * @see #lookup */ protected Object lookupStub() throws RemoteLookupFailureException { try { return lookup(); } catch (NamingException ex) { throw new RemoteLookupFailureException("JNDI lookup for RMI service [" + getJndiName() + "] failed", ex); } }
/** * Refresh the RMI stub and retry the given invocation. * Called by invoke on connect failure. * @param invocation the AOP method invocation * @return the invocation result, if any * @throws Throwable in case of invocation failure * @see #invoke */ @Nullable protected Object refreshAndRetry(MethodInvocation invocation) throws Throwable { Object freshStub; synchronized (this.stubMonitor) { this.cachedStub = null; freshStub = lookupStub(); if (this.cacheStub) { this.cachedStub = freshStub; } } return doInvoke(invocation, freshStub); }
/** * Refresh the stub and retry the remote invocation if necessary. * <p>If not configured to refresh on connect failure, this method * simply rethrows the original exception. * @param invocation the invocation that failed * @param ex the exception raised on remote invocation * @return the result value of the new invocation, if succeeded * @throws Throwable an exception raised by the new invocation, if failed too. */ private Object handleRemoteConnectFailure(MethodInvocation invocation, Exception ex) throws Throwable { if (this.refreshStubOnConnectFailure) { if (logger.isDebugEnabled()) { logger.debug("Could not connect to RMI service [" + getJndiName() + "] - retrying", ex); } else if (logger.isInfoEnabled()) { logger.info("Could not connect to RMI service [" + getJndiName() + "] - retrying"); } return refreshAndRetry(invocation); } else { throw ex; } }
/** * Create a new RemoteInvocation object for the given AOP method invocation. * <p>The default implementation delegates to the configured * {@link #setRemoteInvocationFactory RemoteInvocationFactory}. * This can be overridden in subclasses in order to provide custom RemoteInvocation * subclasses, containing additional invocation parameters (e.g. user credentials). * <p>Note that it is preferable to build a custom RemoteInvocationFactory * as a reusable strategy, instead of overriding this method. * @param methodInvocation the current AOP method invocation * @return the RemoteInvocation object * @see RemoteInvocationFactory#createRemoteInvocation */ protected RemoteInvocation createRemoteInvocation(MethodInvocation methodInvocation) { return getRemoteInvocationFactory().createRemoteInvocation(methodInvocation); }
Object stub; try { stub = getStub(); throw new RemoteLookupFailureException("JNDI lookup for RMI service [" + getJndiName() + "] failed", ex); Context ctx = (this.exposeAccessContext ? getJndiTemplate().getContext() : null); try { return doInvoke(invocation, stub); return handleRemoteConnectFailure(invocation, ex); if (isConnectFailure(ex)) { return handleRemoteConnectFailure(invocation, ex); getJndiTemplate().releaseContext(ctx);
/** * Fetches the RMI stub on startup, if necessary. * @throws RemoteLookupFailureException if RMI stub creation failed * @see #setLookupStubOnStartup * @see #lookupStub */ public void prepare() throws RemoteLookupFailureException { // Cache RMI stub on initialization? if (this.lookupStubOnStartup) { Object remoteObj = lookupStub(); if (logger.isDebugEnabled()) { if (remoteObj instanceof RmiInvocationHandler) { logger.debug("JNDI RMI object [" + getJndiName() + "] is an RMI invoker"); } else if (getServiceInterface() != null) { boolean isImpl = getServiceInterface().isInstance(remoteObj); logger.debug("Using service interface [" + getServiceInterface().getName() + "] for JNDI RMI object [" + getJndiName() + "] - " + (!isImpl ? "not " : "") + "directly implemented"); } } if (this.cacheStub) { this.cachedStub = remoteObj; } } }
return doInvoke(invocation, (RmiInvocationHandler) stub); throw convertRmiAccessException(ex, invocation.getMethod()); "] failed in RMI service [" + getJndiName() + "]", ex); Throwable targetEx = ex.getTargetException(); if (targetEx instanceof RemoteException) { throw convertRmiAccessException((RemoteException) targetEx, invocation.getMethod());