Added "exposeAccessContext" flag JndiRmiClientInterceptor/ProxyFactoryBean (for WebLogic)

Issue: SPR-9428
This commit is contained in:
Juergen Hoeller 2013-01-18 16:51:21 +01:00
parent 701c5f1110
commit cca255bc79
1 changed files with 26 additions and 7 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2012 the original author or authors. * Copyright 2002-2013 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -19,7 +19,7 @@ package org.springframework.remoting.rmi;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.rmi.RemoteException; import java.rmi.RemoteException;
import javax.naming.Context;
import javax.naming.NamingException; import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject; import javax.rmi.PortableRemoteObject;
@ -88,6 +88,8 @@ public class JndiRmiClientInterceptor extends JndiObjectLocator implements Metho
private boolean refreshStubOnConnectFailure = false; private boolean refreshStubOnConnectFailure = false;
private boolean exposeAccessContext = false;
private Object cachedStub; private Object cachedStub;
private final Object stubMonitor = new Object(); private final Object stubMonitor = new Object();
@ -166,6 +168,18 @@ public class JndiRmiClientInterceptor extends JndiObjectLocator implements Metho
this.refreshStubOnConnectFailure = refreshStubOnConnectFailure; this.refreshStubOnConnectFailure = refreshStubOnConnectFailure;
} }
/**
* Set whether to expose the JNDI environment context for all access to the target
* RMI stub, i.e. for all method invocations on the exposed object reference.
* <p>Default is "false", i.e. to only expose the JNDI context for object lookup.
* Switch this flag to "true" in order to expose the JNDI environment (including
* the authorization context) for each RMI invocation, as needed by WebLogic
* for RMI stubs with authorization requirements.
*/
public void setExposeAccessContext(boolean exposeAccessContext) {
this.exposeAccessContext = exposeAccessContext;
}
@Override @Override
public void afterPropertiesSet() throws NamingException { public void afterPropertiesSet() throws NamingException {
@ -190,8 +204,8 @@ public class JndiRmiClientInterceptor extends JndiObjectLocator implements Metho
else if (getServiceInterface() != null) { else if (getServiceInterface() != null) {
boolean isImpl = getServiceInterface().isInstance(remoteObj); boolean isImpl = getServiceInterface().isInstance(remoteObj);
logger.debug("Using service interface [" + getServiceInterface().getName() + logger.debug("Using service interface [" + getServiceInterface().getName() +
"] for JNDI RMI object [" + getJndiName() + "] - " + "] for JNDI RMI object [" + getJndiName() + "] - " +
(!isImpl ? "not " : "") + "directly implemented"); (!isImpl ? "not " : "") + "directly implemented");
} }
} }
if (this.cacheStub) { if (this.cacheStub) {
@ -268,13 +282,15 @@ public class JndiRmiClientInterceptor extends JndiObjectLocator implements Metho
* @see java.rmi.NoSuchObjectException * @see java.rmi.NoSuchObjectException
*/ */
public Object invoke(MethodInvocation invocation) throws Throwable { public Object invoke(MethodInvocation invocation) throws Throwable {
Object stub = null; Object stub;
try { try {
stub = getStub(); stub = getStub();
} }
catch (NamingException ex) { catch (NamingException ex) {
throw new RemoteLookupFailureException("JNDI lookup for RMI service [" + getJndiName() + "] failed", ex); throw new RemoteLookupFailureException("JNDI lookup for RMI service [" + getJndiName() + "] failed", ex);
} }
Context ctx = (this.exposeAccessContext ? getJndiTemplate().getContext() : null);
try { try {
return doInvoke(invocation, stub); return doInvoke(invocation, stub);
} }
@ -297,6 +313,9 @@ public class JndiRmiClientInterceptor extends JndiObjectLocator implements Metho
throw ex; throw ex;
} }
} }
finally {
getJndiTemplate().releaseContext(ctx);
}
} }
/** /**
@ -354,7 +373,7 @@ public class JndiRmiClientInterceptor extends JndiObjectLocator implements Metho
* @see #invoke * @see #invoke
*/ */
protected Object refreshAndRetry(MethodInvocation invocation) throws Throwable { protected Object refreshAndRetry(MethodInvocation invocation) throws Throwable {
Object freshStub = null; Object freshStub;
synchronized (this.stubMonitor) { synchronized (this.stubMonitor) {
this.cachedStub = null; this.cachedStub = null;
freshStub = lookupStub(); freshStub = lookupStub();
@ -426,7 +445,7 @@ public class JndiRmiClientInterceptor extends JndiObjectLocator implements Metho
* @see org.springframework.remoting.support.RemoteInvocation * @see org.springframework.remoting.support.RemoteInvocation
*/ */
protected Object doInvoke(MethodInvocation methodInvocation, RmiInvocationHandler invocationHandler) protected Object doInvoke(MethodInvocation methodInvocation, RmiInvocationHandler invocationHandler)
throws RemoteException, NoSuchMethodException, IllegalAccessException, InvocationTargetException { throws RemoteException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
if (AopUtils.isToStringMethod(methodInvocation.getMethod())) { if (AopUtils.isToStringMethod(methodInvocation.getMethod())) {
return "RMI invoker proxy for service URL [" + getJndiName() + "]"; return "RMI invoker proxy for service URL [" + getJndiName() + "]";