001/*
002 * Copyright 2002-2012 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.remoting.rmi;
018
019import javax.naming.NamingException;
020
021import org.springframework.aop.framework.ProxyFactory;
022import org.springframework.beans.factory.BeanClassLoaderAware;
023import org.springframework.beans.factory.FactoryBean;
024import org.springframework.util.ClassUtils;
025
026/**
027 * {@link FactoryBean} for RMI proxies from JNDI.
028 *
029 * <p>Typically used for RMI-IIOP (CORBA), but can also be used for EJB home objects
030 * (for example, a Stateful Session Bean home). In contrast to a plain JNDI lookup,
031 * this accessor also performs narrowing through {@link javax.rmi.PortableRemoteObject}.
032 *
033 * <p>With conventional RMI services, this invoker is typically used with the RMI
034 * service interface. Alternatively, this invoker can also proxy a remote RMI service
035 * with a matching non-RMI business interface, i.e. an interface that mirrors the RMI
036 * service methods but does not declare RemoteExceptions. In the latter case,
037 * RemoteExceptions thrown by the RMI stub will automatically get converted to
038 * Spring's unchecked RemoteAccessException.
039 *
040 * <p>The JNDI environment can be specified as "jndiEnvironment" property,
041 * or be configured in a {@code jndi.properties} file or as system properties.
042 * For example:
043 *
044 * <pre class="code">&lt;property name="jndiEnvironment"&gt;
045 *       &lt;props>
046 *               &lt;prop key="java.naming.factory.initial"&gt;com.sun.jndi.cosnaming.CNCtxFactory&lt;/prop&gt;
047 *               &lt;prop key="java.naming.provider.url"&gt;iiop://localhost:1050&lt;/prop&gt;
048 *       &lt;/props&gt;
049 * &lt;/property&gt;</pre>
050 *
051 * @author Juergen Hoeller
052 * @since 1.1
053 * @see #setServiceInterface
054 * @see #setJndiName
055 * @see #setJndiTemplate
056 * @see #setJndiEnvironment
057 * @see #setJndiName
058 * @see JndiRmiServiceExporter
059 * @see org.springframework.remoting.RemoteAccessException
060 * @see java.rmi.RemoteException
061 * @see java.rmi.Remote
062 * @see javax.rmi.PortableRemoteObject#narrow
063 */
064public class JndiRmiProxyFactoryBean extends JndiRmiClientInterceptor
065                implements FactoryBean<Object>, BeanClassLoaderAware {
066
067        private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
068
069        private Object serviceProxy;
070
071
072        @Override
073        public void setBeanClassLoader(ClassLoader classLoader) {
074                this.beanClassLoader = classLoader;
075        }
076
077        @Override
078        public void afterPropertiesSet() throws NamingException {
079                super.afterPropertiesSet();
080                if (getServiceInterface() == null) {
081                        throw new IllegalArgumentException("Property 'serviceInterface' is required");
082                }
083                this.serviceProxy = new ProxyFactory(getServiceInterface(), this).getProxy(this.beanClassLoader);
084        }
085
086
087        @Override
088        public Object getObject() {
089                return this.serviceProxy;
090        }
091
092        @Override
093        public Class<?> getObjectType() {
094                return getServiceInterface();
095        }
096
097        @Override
098        public boolean isSingleton() {
099                return true;
100        }
101
102}