Source Code Cross Referenced for RmiServiceExporter.java in  » J2EE » spring-framework-2.0.6 » org » springframework » remoting » rmi » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » J2EE » spring framework 2.0.6 » org.springframework.remoting.rmi 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2002-2007 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:         *      http://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:
017:        package org.springframework.remoting.rmi;
018:
019:        import java.rmi.AlreadyBoundException;
020:        import java.rmi.NoSuchObjectException;
021:        import java.rmi.NotBoundException;
022:        import java.rmi.Remote;
023:        import java.rmi.RemoteException;
024:        import java.rmi.registry.LocateRegistry;
025:        import java.rmi.registry.Registry;
026:        import java.rmi.server.RMIClientSocketFactory;
027:        import java.rmi.server.RMIServerSocketFactory;
028:        import java.rmi.server.UnicastRemoteObject;
029:
030:        import org.springframework.beans.factory.DisposableBean;
031:        import org.springframework.beans.factory.InitializingBean;
032:
033:        /**
034:         * RMI exporter that exposes the specified service as RMI object with the specified name.
035:         * Such services can be accessed via plain RMI or via {@link RmiProxyFactoryBean}.
036:         * Also supports exposing any non-RMI service via RMI invokers, to be accessed via
037:         * {@link RmiClientInterceptor} / {@link RmiProxyFactoryBean}'s automatic detection
038:         * of such invokers.
039:         *
040:         * <p>With an RMI invoker, RMI communication works on the {@link RmiInvocationHandler}
041:         * level, needing only one stub for any service. Service interfaces do not have to
042:         * extend <code>java.rmi.Remote</code> or throw <code>java.rmi.RemoteException</code>
043:         * on all methods, but in and out parameters have to be serializable.
044:         *
045:         * <p>The major advantage of RMI, compared to Hessian and Burlap, is serialization.
046:         * Effectively, any serializable Java object can be transported without hassle.
047:         * Hessian and Burlap have their own (de-)serialization mechanisms, but are
048:         * HTTP-based and thus much easier to setup than RMI. Alternatively, consider
049:         * Spring's HTTP invoker to combine Java serialization with HTTP-based transport.
050:         *
051:         * <p>Note: RMI makes a best-effort attempt to obtain the fully qualified host name.
052:         * If one cannot be determined, it will fall back and use the IP address. Depending
053:         * on your network configuration, in some cases it will resolve the IP to the loopback
054:         * address. To ensure that RMI will use the host name bound to the correct network
055:         * interface, you should pass the <code>java.rmi.server.hostname</code> property to the
056:         * JVM that will export the registry and/or the service using the "-D" JVM argument.
057:         * For example: <code>-Djava.rmi.server.hostname=myserver.com</code>
058:         *
059:         * @author Juergen Hoeller
060:         * @since 13.05.2003
061:         * @see RmiClientInterceptor
062:         * @see RmiProxyFactoryBean
063:         * @see java.rmi.Remote
064:         * @see java.rmi.RemoteException
065:         * @see org.springframework.remoting.caucho.HessianServiceExporter
066:         * @see org.springframework.remoting.caucho.BurlapServiceExporter
067:         * @see org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter
068:         */
069:        public class RmiServiceExporter extends RmiBasedExporter implements 
070:                InitializingBean, DisposableBean {
071:
072:            private String serviceName;
073:
074:            private int servicePort = 0; // anonymous port
075:
076:            private RMIClientSocketFactory clientSocketFactory;
077:
078:            private RMIServerSocketFactory serverSocketFactory;
079:
080:            private Registry registry;
081:
082:            private String registryHost;
083:
084:            private int registryPort = Registry.REGISTRY_PORT;
085:
086:            private RMIClientSocketFactory registryClientSocketFactory;
087:
088:            private RMIServerSocketFactory registryServerSocketFactory;
089:
090:            private boolean alwaysCreateRegistry = false;
091:
092:            private boolean replaceExistingBinding = true;
093:
094:            private Remote exportedObject;
095:
096:            /**
097:             * Set the name of the exported RMI service,
098:             * i.e. <code>rmi://host:port/NAME</code>
099:             */
100:            public void setServiceName(String serviceName) {
101:                this .serviceName = serviceName;
102:            }
103:
104:            /**
105:             * Set the port that the exported RMI service will use.
106:             * <p>Default is 0 (anonymous port).
107:             */
108:            public void setServicePort(int servicePort) {
109:                this .servicePort = servicePort;
110:            }
111:
112:            /**
113:             * Set a custom RMI client socket factory to use for exporting the service.
114:             * <p>If the given object also implements <code>java.rmi.server.RMIServerSocketFactory</code>,
115:             * it will automatically be registered as server socket factory too.
116:             * @see #setServerSocketFactory
117:             * @see java.rmi.server.RMIClientSocketFactory
118:             * @see java.rmi.server.RMIServerSocketFactory
119:             * @see UnicastRemoteObject#exportObject(Remote, int, RMIClientSocketFactory, RMIServerSocketFactory)
120:             */
121:            public void setClientSocketFactory(
122:                    RMIClientSocketFactory clientSocketFactory) {
123:                this .clientSocketFactory = clientSocketFactory;
124:            }
125:
126:            /**
127:             * Set a custom RMI server socket factory to use for exporting the service.
128:             * <p>Only needs to be specified when the client socket factory does not
129:             * implement <code>java.rmi.server.RMIServerSocketFactory</code> already.
130:             * @see #setClientSocketFactory
131:             * @see java.rmi.server.RMIClientSocketFactory
132:             * @see java.rmi.server.RMIServerSocketFactory
133:             * @see UnicastRemoteObject#exportObject(Remote, int, RMIClientSocketFactory, RMIServerSocketFactory)
134:             */
135:            public void setServerSocketFactory(
136:                    RMIServerSocketFactory serverSocketFactory) {
137:                this .serverSocketFactory = serverSocketFactory;
138:            }
139:
140:            /**
141:             * Specify the RMI registry to register the exported service with.
142:             * Typically used in combination with RmiRegistryFactoryBean.
143:             * <p>Alternatively, you can specify all registry properties locally.
144:             * This exporter will then try to locate the specified registry,
145:             * automatically creating a new local one if appropriate.
146:             * <p>Default is a local registry at the default port (1099),
147:             * created on the fly if necessary.
148:             * @see RmiRegistryFactoryBean
149:             * @see #setRegistryHost
150:             * @see #setRegistryPort
151:             * @see #setRegistryClientSocketFactory
152:             * @see #setRegistryServerSocketFactory
153:             */
154:            public void setRegistry(Registry registry) {
155:                this .registry = registry;
156:            }
157:
158:            /**
159:             * Set the host of the registry for the exported RMI service,
160:             * i.e. <code>rmi://HOST:port/name</code>
161:             * <p>Default is localhost.
162:             */
163:            public void setRegistryHost(String registryHost) {
164:                this .registryHost = registryHost;
165:            }
166:
167:            /**
168:             * Set the port of the registry for the exported RMI service,
169:             * i.e. <code>rmi://host:PORT/name</code>
170:             * <p>Default is <code>Registry.REGISTRY_PORT</code> (1099).
171:             * @see java.rmi.registry.Registry#REGISTRY_PORT
172:             */
173:            public void setRegistryPort(int registryPort) {
174:                this .registryPort = registryPort;
175:            }
176:
177:            /**
178:             * Set a custom RMI client socket factory to use for the RMI registry.
179:             * <p>If the given object also implements <code>java.rmi.server.RMIServerSocketFactory</code>,
180:             * it will automatically be registered as server socket factory too.
181:             * @see #setRegistryServerSocketFactory
182:             * @see java.rmi.server.RMIClientSocketFactory
183:             * @see java.rmi.server.RMIServerSocketFactory
184:             * @see LocateRegistry#getRegistry(String, int, RMIClientSocketFactory)
185:             */
186:            public void setRegistryClientSocketFactory(
187:                    RMIClientSocketFactory registryClientSocketFactory) {
188:                this .registryClientSocketFactory = registryClientSocketFactory;
189:            }
190:
191:            /**
192:             * Set a custom RMI server socket factory to use for the RMI registry.
193:             * <p>Only needs to be specified when the client socket factory does not
194:             * implement <code>java.rmi.server.RMIServerSocketFactory</code> already.
195:             * @see #setRegistryClientSocketFactory
196:             * @see java.rmi.server.RMIClientSocketFactory
197:             * @see java.rmi.server.RMIServerSocketFactory
198:             * @see LocateRegistry#createRegistry(int, RMIClientSocketFactory, RMIServerSocketFactory)
199:             */
200:            public void setRegistryServerSocketFactory(
201:                    RMIServerSocketFactory registryServerSocketFactory) {
202:                this .registryServerSocketFactory = registryServerSocketFactory;
203:            }
204:
205:            /**
206:             * Set whether to always create the registry in-process,
207:             * not attempting to locate an existing registry at the specified port.
208:             * <p>Default is "false". Switch this flag to "true" in order to avoid
209:             * the overhead of locating an existing registry when you always
210:             * intend to create a new registry in any case.
211:             */
212:            public void setAlwaysCreateRegistry(boolean alwaysCreateRegistry) {
213:                this .alwaysCreateRegistry = alwaysCreateRegistry;
214:            }
215:
216:            /**
217:             * Set whether to replace an existing binding in the RMI registry,
218:             * that is, whether to simply override an existing binding with the
219:             * specified service in case of a naming conflict in the registry.
220:             * <p>Default is "true", assuming that an existing binding for this
221:             * exporter's service name is an accidental leftover from a previous
222:             * execution. Switch this to "false" to make the exporter fail in such
223:             * a scenario, indicating that there was already an RMI object bound.
224:             */
225:            public void setReplaceExistingBinding(boolean replaceExistingBinding) {
226:                this .replaceExistingBinding = replaceExistingBinding;
227:            }
228:
229:            public void afterPropertiesSet() throws RemoteException {
230:                prepare();
231:            }
232:
233:            /**
234:             * Initialize this service exporter, registering the service as RMI object.
235:             * <p>Creates an RMI registry on the specified port if none exists.
236:             * @throws RemoteException if service registration failed
237:             */
238:            public void prepare() throws RemoteException {
239:                checkService();
240:
241:                if (this .serviceName == null) {
242:                    throw new IllegalArgumentException(
243:                            "Property 'serviceName' is required");
244:                }
245:
246:                // Check socket factories for exported object.
247:                if (this .clientSocketFactory instanceof  RMIServerSocketFactory) {
248:                    this .serverSocketFactory = (RMIServerSocketFactory) this .clientSocketFactory;
249:                }
250:                if ((this .clientSocketFactory != null && this .serverSocketFactory == null)
251:                        || (this .clientSocketFactory == null && this .serverSocketFactory != null)) {
252:                    throw new IllegalArgumentException(
253:                            "Both RMIClientSocketFactory and RMIServerSocketFactory or none required");
254:                }
255:
256:                // Check socket factories for RMI registry.
257:                if (this .registryClientSocketFactory instanceof  RMIServerSocketFactory) {
258:                    this .registryServerSocketFactory = (RMIServerSocketFactory) this .registryClientSocketFactory;
259:                }
260:                if (this .registryClientSocketFactory == null
261:                        && this .registryServerSocketFactory != null) {
262:                    throw new IllegalArgumentException(
263:                            "RMIServerSocketFactory without RMIClientSocketFactory for registry not supported");
264:                }
265:
266:                // Determine RMI registry to use.
267:                if (this .registry == null) {
268:                    this .registry = getRegistry(this .registryHost,
269:                            this .registryPort,
270:                            this .registryClientSocketFactory,
271:                            this .registryServerSocketFactory);
272:                }
273:
274:                // Initialize and cache exported object.
275:                this .exportedObject = getObjectToExport();
276:
277:                if (logger.isInfoEnabled()) {
278:                    logger.info("Binding service '" + this .serviceName
279:                            + "' to RMI registry: " + this .registry);
280:                }
281:
282:                // Export RMI object.
283:                if (this .clientSocketFactory != null) {
284:                    UnicastRemoteObject.exportObject(this .exportedObject,
285:                            this .servicePort, this .clientSocketFactory,
286:                            this .serverSocketFactory);
287:                } else {
288:                    UnicastRemoteObject.exportObject(this .exportedObject,
289:                            this .servicePort);
290:                }
291:
292:                // Bind RMI object to registry.
293:                try {
294:                    if (this .replaceExistingBinding) {
295:                        this .registry.rebind(this .serviceName,
296:                                this .exportedObject);
297:                    } else {
298:                        this .registry.bind(this .serviceName,
299:                                this .exportedObject);
300:                    }
301:                } catch (AlreadyBoundException ex) {
302:                    // Already an RMI object bound for the specified service name...
303:                    unexportObjectSilently();
304:                    throw new IllegalStateException(
305:                            "Already an RMI object bound for name '"
306:                                    + this .serviceName + "': " + ex.toString());
307:                } catch (RemoteException ex) {
308:                    // Registry binding failed: let's unexport the RMI object as well.
309:                    unexportObjectSilently();
310:                    throw ex;
311:                }
312:            }
313:
314:            /**
315:             * Locate or create the RMI registry for this exporter.
316:             * @param registryHost the registry host to use (if this is specified,
317:             * no implicit creation of a RMI registry will happen)
318:             * @param registryPort the registry port to use
319:             * @param clientSocketFactory the RMI client socket factory for the registry (if any)
320:             * @param serverSocketFactory the RMI server socket factory for the registry (if any)
321:             * @return the RMI registry
322:             * @throws RemoteException if the registry couldn't be located or created
323:             */
324:            protected Registry getRegistry(String registryHost,
325:                    int registryPort,
326:                    RMIClientSocketFactory clientSocketFactory,
327:                    RMIServerSocketFactory serverSocketFactory)
328:                    throws RemoteException {
329:
330:                if (registryHost != null) {
331:                    // Host explictly specified: only lookup possible.
332:                    if (logger.isInfoEnabled()) {
333:                        logger.info("Looking for RMI registry at port '"
334:                                + registryPort + "' of host [" + registryHost
335:                                + "]");
336:                    }
337:                    Registry reg = LocateRegistry.getRegistry(registryHost,
338:                            registryPort, clientSocketFactory);
339:                    testRegistry(reg);
340:                    return reg;
341:                }
342:
343:                else {
344:                    return getRegistry(registryPort, clientSocketFactory,
345:                            serverSocketFactory);
346:                }
347:            }
348:
349:            /**
350:             * Locate or create the RMI registry for this exporter.
351:             * @param registryPort the registry port to use
352:             * @param clientSocketFactory the RMI client socket factory for the registry (if any)
353:             * @param serverSocketFactory the RMI server socket factory for the registry (if any)
354:             * @return the RMI registry
355:             * @throws RemoteException if the registry couldn't be located or created
356:             */
357:            protected Registry getRegistry(int registryPort,
358:                    RMIClientSocketFactory clientSocketFactory,
359:                    RMIServerSocketFactory serverSocketFactory)
360:                    throws RemoteException {
361:
362:                if (clientSocketFactory != null) {
363:                    if (this .alwaysCreateRegistry) {
364:                        logger.info("Creating new RMI registry");
365:                        return LocateRegistry.createRegistry(registryPort,
366:                                clientSocketFactory, serverSocketFactory);
367:                    }
368:                    if (logger.isInfoEnabled()) {
369:                        logger.info("Looking for RMI registry at port '"
370:                                + registryPort
371:                                + "', using custom socket factory");
372:                    }
373:                    try {
374:                        // Retrieve existing registry.
375:                        Registry reg = LocateRegistry.getRegistry(null,
376:                                registryPort, clientSocketFactory);
377:                        testRegistry(reg);
378:                        return reg;
379:                    } catch (RemoteException ex) {
380:                        logger.debug("RMI registry access threw exception", ex);
381:                        logger
382:                                .info("Could not detect RMI registry - creating new one");
383:                        // Assume no registry found -> create new one.
384:                        return LocateRegistry.createRegistry(registryPort,
385:                                clientSocketFactory, serverSocketFactory);
386:                    }
387:                }
388:
389:                else {
390:                    return getRegistry(registryPort);
391:                }
392:            }
393:
394:            /**
395:             * Locate or create the RMI registry for this exporter.
396:             * @param registryPort the registry port to use
397:             * @return the RMI registry
398:             * @throws RemoteException if the registry couldn't be located or created
399:             */
400:            protected Registry getRegistry(int registryPort)
401:                    throws RemoteException {
402:                if (this .alwaysCreateRegistry) {
403:                    logger.info("Creating new RMI registry");
404:                    return LocateRegistry.createRegistry(registryPort);
405:                }
406:                if (logger.isInfoEnabled()) {
407:                    logger.info("Looking for RMI registry at port '"
408:                            + registryPort + "'");
409:                }
410:                try {
411:                    // Retrieve existing registry.
412:                    Registry reg = LocateRegistry.getRegistry(registryPort);
413:                    testRegistry(reg);
414:                    return reg;
415:                } catch (RemoteException ex) {
416:                    logger.debug("RMI registry access threw exception", ex);
417:                    logger
418:                            .info("Could not detect RMI registry - creating new one");
419:                    // Assume no registry found -> create new one.
420:                    return LocateRegistry.createRegistry(registryPort);
421:                }
422:            }
423:
424:            /**
425:             * Test the given RMI registry, calling some operation on it to
426:             * check whether it is still active.
427:             * <p>Default implementation calls <code>Registry.list()</code>.
428:             * @param registry the RMI registry to test
429:             * @throws RemoteException if thrown by registry methods
430:             * @see java.rmi.registry.Registry#list()
431:             */
432:            protected void testRegistry(Registry registry)
433:                    throws RemoteException {
434:                registry.list();
435:            }
436:
437:            /**
438:             * Unbind the RMI service from the registry on bean factory shutdown.
439:             */
440:            public void destroy() throws RemoteException {
441:                if (logger.isInfoEnabled()) {
442:                    logger.info("Unbinding RMI service '" + this .serviceName
443:                            + "' from registry at port '" + this .registryPort
444:                            + "'");
445:                }
446:                try {
447:                    this .registry.unbind(this .serviceName);
448:                } catch (NotBoundException ex) {
449:                    if (logger.isWarnEnabled()) {
450:                        logger.warn("RMI service '" + this .serviceName
451:                                + "' is not bound to registry at port '"
452:                                + this .registryPort + "' anymore", ex);
453:                    }
454:                } finally {
455:                    unexportObjectSilently();
456:                }
457:            }
458:
459:            /**
460:             * Unexport the registered RMI object, logging any exception that arises.
461:             */
462:            private void unexportObjectSilently() {
463:                try {
464:                    UnicastRemoteObject.unexportObject(this .exportedObject,
465:                            true);
466:                } catch (NoSuchObjectException ex) {
467:                    if (logger.isWarnEnabled()) {
468:                        logger.warn(
469:                                "RMI object for service '" + this .serviceName
470:                                        + "' isn't exported anymore", ex);
471:                    }
472:                }
473:            }
474:
475:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.