KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > remoting > rmi > RmiRegistryFactoryBean


1 /*
2  * Copyright 2002-2007 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.springframework.remoting.rmi;
18
19 import java.rmi.RemoteException JavaDoc;
20 import java.rmi.registry.LocateRegistry JavaDoc;
21 import java.rmi.registry.Registry JavaDoc;
22 import java.rmi.server.RMIClientSocketFactory JavaDoc;
23 import java.rmi.server.RMIServerSocketFactory JavaDoc;
24 import java.rmi.server.UnicastRemoteObject JavaDoc;
25
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28
29 import org.springframework.beans.factory.DisposableBean;
30 import org.springframework.beans.factory.FactoryBean;
31 import org.springframework.beans.factory.InitializingBean;
32
33 /**
34  * FactoryBean that locates a {@link java.rmi.registry.Registry} and
35  * exposes it for bean references. Can also create a local RMI registry
36  * on the fly if none exists already.
37  *
38  * <p>Can be used to set up and pass around the actual Registry object to
39  * applications objects that need to work with RMI. One example for such an
40  * object that needs to work with RMI is Spring's {@link RmiServiceExporter},
41  * which either works with a passed-in Registry reference or falls back to
42  * the registry as specified by its local properties and defaults.
43  *
44  * <p>Also useful to enforce creation of a local RMI registry at a given port,
45  * for example for a JMX connector. If used in conjunction with
46  * {@link org.springframework.jmx.support.ConnectorServerFactoryBean},
47  * it is recommended to mark the connector definition (ConnectorServerFactoryBean)
48  * as "depends-on" the registry definition (RmiRegistryFactoryBean),
49  * to guarantee starting up the registry first.
50  *
51  * <p>Note: The implementation of this class mirrors the corresponding logic
52  * in {@link RmiServiceExporter}, and also offers the same customization hooks.
53  * RmiServiceExporter implements its own registry lookup as a convenience:
54  * It is very common to simply rely on the registry defaults.
55  *
56  * @author Juergen Hoeller
57  * @since 1.2.3
58  * @see RmiServiceExporter#setRegistry
59  * @see org.springframework.jmx.support.ConnectorServerFactoryBean
60  * @see java.rmi.registry.Registry
61  * @see java.rmi.registry.LocateRegistry
62  */

63 public class RmiRegistryFactoryBean implements FactoryBean, InitializingBean, DisposableBean {
64
65     protected final Log logger = LogFactory.getLog(getClass());
66
67     private String JavaDoc host;
68
69     private int port = Registry.REGISTRY_PORT;
70
71     private RMIClientSocketFactory JavaDoc clientSocketFactory;
72
73     private RMIServerSocketFactory JavaDoc serverSocketFactory;
74
75     private Registry JavaDoc registry;
76
77     private boolean alwaysCreate = false;
78
79     private boolean created = false;
80
81
82     /**
83      * Set the host of the registry for the exported RMI service,
84      * i.e. <code>rmi://HOST:port/name</code>
85      * <p>Default is localhost.
86      */

87     public void setHost(String JavaDoc host) {
88         this.host = host;
89     }
90
91     /**
92      * Return the host of the registry for the exported RMI service.
93      */

94     public String JavaDoc getHost() {
95         return this.host;
96     }
97
98     /**
99      * Set the port of the registry for the exported RMI service,
100      * i.e. <code>rmi://host:PORT/name</code>
101      * <p>Default is <code>Registry.REGISTRY_PORT</code> (1099).
102      */

103     public void setPort(int port) {
104         this.port = port;
105     }
106
107     /**
108      * Return the port of the registry for the exported RMI service.
109      */

110     public int getPort() {
111         return this.port;
112     }
113
114     /**
115      * Set a custom RMI client socket factory to use for the RMI registry.
116      * <p>If the given object also implements <code>java.rmi.server.RMIServerSocketFactory</code>,
117      * it will automatically be registered as server socket factory too.
118      * @see #setServerSocketFactory
119      * @see java.rmi.server.RMIClientSocketFactory
120      * @see java.rmi.server.RMIServerSocketFactory
121      * @see java.rmi.registry.LocateRegistry#getRegistry(String, int, java.rmi.server.RMIClientSocketFactory)
122      */

123     public void setClientSocketFactory(RMIClientSocketFactory JavaDoc clientSocketFactory) {
124         this.clientSocketFactory = clientSocketFactory;
125     }
126
127     /**
128      * Set a custom RMI server socket factory to use for the RMI registry.
129      * <p>Only needs to be specified when the client socket factory does not
130      * implement <code>java.rmi.server.RMIServerSocketFactory</code> already.
131      * @see #setClientSocketFactory
132      * @see java.rmi.server.RMIClientSocketFactory
133      * @see java.rmi.server.RMIServerSocketFactory
134      * @see java.rmi.registry.LocateRegistry#createRegistry(int, RMIClientSocketFactory, java.rmi.server.RMIServerSocketFactory)
135      */

136     public void setServerSocketFactory(RMIServerSocketFactory JavaDoc serverSocketFactory) {
137         this.serverSocketFactory = serverSocketFactory;
138     }
139
140     /**
141      * Set whether to always create the registry in-process,
142      * not attempting to locate an existing registry at the specified port.
143      * <p>Default is "false". Switch this flag to "true" in order to avoid
144      * the overhead of locating an existing registry when you always
145      * intend to create a new registry in any case.
146      */

147     public void setAlwaysCreate(boolean alwaysCreate) {
148         this.alwaysCreate = alwaysCreate;
149     }
150
151
152     public void afterPropertiesSet() throws Exception JavaDoc {
153         // Check socket factories for registry.
154
if (this.clientSocketFactory instanceof RMIServerSocketFactory JavaDoc) {
155             this.serverSocketFactory = (RMIServerSocketFactory JavaDoc) this.clientSocketFactory;
156         }
157         if ((this.clientSocketFactory != null && this.serverSocketFactory == null) ||
158                 (this.clientSocketFactory == null && this.serverSocketFactory != null)) {
159             throw new IllegalArgumentException JavaDoc(
160                     "Both RMIClientSocketFactory and RMIServerSocketFactory or none required");
161         }
162
163         // Fetch RMI registry to expose.
164
this.registry = getRegistry(this.host, this.port, this.clientSocketFactory, this.serverSocketFactory);
165     }
166
167
168     /**
169      * Locate or create the RMI registry.
170      * @param registryHost the registry host to use (if this is specified,
171      * no implicit creation of a RMI registry will happen)
172      * @param registryPort the registry port to use
173      * @param clientSocketFactory the RMI client socket factory for the registry (if any)
174      * @param serverSocketFactory the RMI server socket factory for the registry (if any)
175      * @return the RMI registry
176      * @throws java.rmi.RemoteException if the registry couldn't be located or created
177      */

178     protected Registry JavaDoc getRegistry(String JavaDoc registryHost, int registryPort,
179             RMIClientSocketFactory JavaDoc clientSocketFactory, RMIServerSocketFactory JavaDoc serverSocketFactory)
180             throws RemoteException JavaDoc {
181
182         if (registryHost != null) {
183             // Host explictly specified: only lookup possible.
184
if (logger.isInfoEnabled()) {
185                 logger.info("Looking for RMI registry at port '" + registryPort + "' of host [" + registryHost + "]");
186             }
187             Registry JavaDoc reg = LocateRegistry.getRegistry(registryHost, registryPort, clientSocketFactory);
188             testRegistry(reg);
189             return reg;
190         }
191
192         else {
193             return getRegistry(registryPort, clientSocketFactory, serverSocketFactory);
194         }
195     }
196
197     /**
198      * Locate or create the RMI registry.
199      * @param registryPort the registry port to use
200      * @param clientSocketFactory the RMI client socket factory for the registry (if any)
201      * @param serverSocketFactory the RMI server socket factory for the registry (if any)
202      * @return the RMI registry
203      * @throws RemoteException if the registry couldn't be located or created
204      */

205     protected Registry JavaDoc getRegistry(
206             int registryPort, RMIClientSocketFactory JavaDoc clientSocketFactory, RMIServerSocketFactory JavaDoc serverSocketFactory)
207             throws RemoteException JavaDoc {
208
209         if (clientSocketFactory != null) {
210             if (this.alwaysCreate) {
211                 logger.info("Creating new RMI registry");
212                 this.created = true;
213                 return LocateRegistry.createRegistry(registryPort, clientSocketFactory, serverSocketFactory);
214             }
215             if (logger.isInfoEnabled()) {
216                 logger.info("Looking for RMI registry at port '" + registryPort + "', using custom socket factory");
217             }
218             try {
219                 // Retrieve existing registry.
220
Registry JavaDoc reg = LocateRegistry.getRegistry(null, registryPort, clientSocketFactory);
221                 testRegistry(reg);
222                 return reg;
223             }
224             catch (RemoteException JavaDoc ex) {
225                 logger.debug("RMI registry access threw exception", ex);
226                 logger.info("Could not detect RMI registry - creating new one");
227                 // Assume no registry found -> create new one.
228
this.created = true;
229                 return LocateRegistry.createRegistry(registryPort, clientSocketFactory, serverSocketFactory);
230             }
231         }
232
233         else {
234             return getRegistry(registryPort);
235         }
236     }
237
238     /**
239      * Locate or create the RMI registry.
240      * @param registryPort the registry port to use
241      * @return the RMI registry
242      * @throws RemoteException if the registry couldn't be located or created
243      */

244     protected Registry JavaDoc getRegistry(int registryPort) throws RemoteException JavaDoc {
245         if (this.alwaysCreate) {
246             logger.info("Creating new RMI registry");
247             this.created = true;
248             return LocateRegistry.createRegistry(registryPort);
249         }
250         if (logger.isInfoEnabled()) {
251             logger.info("Looking for RMI registry at port '" + registryPort + "'");
252         }
253         try {
254             // Retrieve existing registry.
255
Registry JavaDoc reg = LocateRegistry.getRegistry(registryPort);
256             testRegistry(reg);
257             return reg;
258         }
259         catch (RemoteException JavaDoc ex) {
260             logger.debug("RMI registry access threw exception", ex);
261             logger.info("Could not detect RMI registry - creating new one");
262             // Assume no registry found -> create new one.
263
this.created = true;
264             return LocateRegistry.createRegistry(registryPort);
265         }
266     }
267
268     /**
269      * Test the given RMI registry, calling some operation on it to
270      * check whether it is still active.
271      * <p>Default implementation calls <code>Registry.list()</code>.
272      * @param registry the RMI registry to test
273      * @throws RemoteException if thrown by registry methods
274      * @see java.rmi.registry.Registry#list()
275      */

276     protected void testRegistry(Registry JavaDoc registry) throws RemoteException JavaDoc {
277         registry.list();
278     }
279
280
281     public Object JavaDoc getObject() throws Exception JavaDoc {
282         return this.registry;
283     }
284
285     public Class JavaDoc getObjectType() {
286         return (this.registry != null ? this.registry.getClass() : Registry JavaDoc.class);
287     }
288
289     public boolean isSingleton() {
290         return true;
291     }
292
293
294     /**
295      * Unexport the RMI registry on bean factory shutdown,
296      * provided that this bean actually created a registry.
297      */

298     public void destroy() throws RemoteException JavaDoc {
299         if (this.created) {
300             logger.info("Unexporting RMI registry");
301             UnicastRemoteObject.unexportObject(this.registry, true);
302         }
303     }
304
305 }
306
Popular Tags