11/*
2- * Copyright 2002-2008 the original author or authors.
2+ * Copyright 2002-2013 the original author or authors.
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
1919import java .lang .reflect .InvocationTargetException ;
2020import java .lang .reflect .Method ;
2121import java .rmi .RemoteException ;
22-
22+ import javax . naming . Context ;
2323import javax .naming .NamingException ;
2424import javax .rmi .PortableRemoteObject ;
2525
5454 * Spring's unchecked RemoteAccessException.
5555 *
5656 * <p>The JNDI environment can be specified as "jndiEnvironment" property,
57- * or be configured in a < code> jndi.properties</code> file or as system properties.
57+ * or be configured in a {@ code jndi.properties} file or as system properties.
5858 * For example:
5959 *
6060 * <pre class="code"><property name="jndiEnvironment">
@@ -88,6 +88,8 @@ public class JndiRmiClientInterceptor extends JndiObjectLocator implements Metho
8888
8989 private boolean refreshStubOnConnectFailure = false ;
9090
91+ private boolean exposeAccessContext = false ;
92+
9193 private Object cachedStub ;
9294
9395 private final Object stubMonitor = new Object ();
@@ -166,6 +168,18 @@ public void setRefreshStubOnConnectFailure(boolean refreshStubOnConnectFailure)
166168 this .refreshStubOnConnectFailure = refreshStubOnConnectFailure ;
167169 }
168170
171+ /**
172+ * Set whether to expose the JNDI environment context for all access to the target
173+ * RMI stub, i.e. for all method invocations on the exposed object reference.
174+ * <p>Default is "false", i.e. to only expose the JNDI context for object lookup.
175+ * Switch this flag to "true" in order to expose the JNDI environment (including
176+ * the authorization context) for each RMI invocation, as needed by WebLogic
177+ * for RMI stubs with authorization requirements.
178+ */
179+ public void setExposeAccessContext (boolean exposeAccessContext ) {
180+ this .exposeAccessContext = exposeAccessContext ;
181+ }
182+
169183
170184 @ Override
171185 public void afterPropertiesSet () throws NamingException {
@@ -190,8 +204,8 @@ public void prepare() throws RemoteLookupFailureException {
190204 else if (getServiceInterface () != null ) {
191205 boolean isImpl = getServiceInterface ().isInstance (remoteObj );
192206 logger .debug ("Using service interface [" + getServiceInterface ().getName () +
193- "] for JNDI RMI object [" + getJndiName () + "] - " +
194- (!isImpl ? "not " : "" ) + "directly implemented" );
207+ "] for JNDI RMI object [" + getJndiName () + "] - " +
208+ (!isImpl ? "not " : "" ) + "directly implemented" );
195209 }
196210 }
197211 if (this .cacheStub ) {
@@ -268,13 +282,15 @@ protected Object getStub() throws NamingException, RemoteLookupFailureException
268282 * @see java.rmi.NoSuchObjectException
269283 */
270284 public Object invoke (MethodInvocation invocation ) throws Throwable {
271- Object stub = null ;
285+ Object stub ;
272286 try {
273287 stub = getStub ();
274288 }
275289 catch (NamingException ex ) {
276290 throw new RemoteLookupFailureException ("JNDI lookup for RMI service [" + getJndiName () + "] failed" , ex );
277291 }
292+
293+ Context ctx = (this .exposeAccessContext ? getJndiTemplate ().getContext () : null );
278294 try {
279295 return doInvoke (invocation , stub );
280296 }
@@ -297,6 +313,9 @@ public Object invoke(MethodInvocation invocation) throws Throwable {
297313 throw ex ;
298314 }
299315 }
316+ finally {
317+ getJndiTemplate ().releaseContext (ctx );
318+ }
300319 }
301320
302321 /**
@@ -354,7 +373,7 @@ else if (logger.isWarnEnabled()) {
354373 * @see #invoke
355374 */
356375 protected Object refreshAndRetry (MethodInvocation invocation ) throws Throwable {
357- Object freshStub = null ;
376+ Object freshStub ;
358377 synchronized (this .stubMonitor ) {
359378 this .cachedStub = null ;
360379 freshStub = lookupStub ();
@@ -426,7 +445,7 @@ else if (targetEx instanceof SystemException) {
426445 * @see org.springframework.remoting.support.RemoteInvocation
427446 */
428447 protected Object doInvoke (MethodInvocation methodInvocation , RmiInvocationHandler invocationHandler )
429- throws RemoteException , NoSuchMethodException , IllegalAccessException , InvocationTargetException {
448+ throws RemoteException , NoSuchMethodException , IllegalAccessException , InvocationTargetException {
430449
431450 if (AopUtils .isToStringMethod (methodInvocation .getMethod ())) {
432451 return "RMI invoker proxy for service URL [" + getJndiName () + "]" ;
0 commit comments