001// Copyright (C) 1998-2001 by Jason Hunter <jhunter_AT_acm_DOT_org>. 002// All rights reserved. Use of this class is limited. 003// Please see the LICENSE for more information. 004 005package com.oreilly.servlet; 006 007import java.io.*; 008import java.net.*; 009import java.rmi.*; 010import java.rmi.server.*; 011import java.rmi.registry.*; 012import java.util.*; 013import javax.servlet.*; 014import javax.servlet.http.*; 015 016/** 017 * A superclass for any HTTP servlet that wishes to act as an RMI server 018 * and, additionally, accept raw socket connections. Includes the 019 * functionality from both RemoteHttpServlet and DaemonHttpServlet, by 020 * extending DaemonHttpServlet and re-implementing RemoteHttpServlet. 021 * 022 * @see com.oreilly.servlet.RemoteHttpServlet 023 * @see com.oreilly.servlet.DaemonHttpServlet 024 * 025 * @author <b>Jason Hunter</b>, Copyright © 1998 026 * @version 1.0, 98/09/18 027 */ 028public abstract class RemoteDaemonHttpServlet extends DaemonHttpServlet 029 implements Remote { 030 /** 031 * The registry for the servlet 032 */ 033 protected Registry registry; 034 035 /** 036 * Begins the servlet's RMI operations and begins a thread listening for 037 * socket connections. 038 * Subclasses that override this method must be sure to first call 039 * <tt>super.init(config)</tt>. 040 * 041 * @param config the servlet config 042 * @exception ServletException if a servlet exception occurs 043 */ 044 public void init(ServletConfig config) throws ServletException { 045 super.init(config); 046 try { 047 UnicastRemoteObject.exportObject(this); 048 bind(); 049 } 050 catch (RemoteException e) { 051 log("Problem binding to RMI registry: " + e.getMessage()); 052 } 053 } 054 055 /** 056 * Halts the servlet's RMI operations and halts the thread listening for 057 * socket connections. Subclasses that 058 * override this method must be sure to first call <tt>super.destroy()</tt>. 059 */ 060 public void destroy() { 061 super.destroy(); 062 unbind(); 063 } 064 065 /** 066 * Returns the name under which the servlet should be bound in the 067 * registry. By default the name is the servlet's class name. This 068 * can be overridden with the <tt>registryName</tt> init parameter. 069 * 070 * @return the name under which the servlet should be bound in the registry 071 */ 072 protected String getRegistryName() { 073 // First name choice is the "registryName" init parameter 074 String name = getInitParameter("registryName"); 075 if (name != null) return name; 076 077 // Fallback choice is the name of this class 078 return this.getClass().getName(); 079 } 080 081 /** 082 * Returns the port where the registry should be running. By default 083 * the port is the default registry port (1099). This can be 084 * overridden with the <tt>registryPort</tt> init parameter. 085 * 086 * @return the port for the registry 087 */ 088 protected int getRegistryPort() { 089 // First port choice is the "registryPort" init parameter 090 try { return Integer.parseInt(getInitParameter("registryPort")); } 091 092 // Fallback choice is the default registry port (1099) 093 catch (NumberFormatException e) { return Registry.REGISTRY_PORT; } 094 } 095 096 /** 097 * Binds the servlet to the registry. Creates the registry if necessary. 098 * Logs any errors. 099 */ 100 protected void bind() { 101 // Try to find the appropriate registry already running 102 try { 103 registry = LocateRegistry.getRegistry(getRegistryPort()); 104 registry.list(); // Verify it's alive and well 105 } 106 catch (Exception e) { 107 // Couldn't get a valid registry 108 registry = null; 109 } 110 111 // If we couldn't find it, we need to create it. 112 // (Equivalent to running "rmiregistry") 113 if (registry == null) { 114 try { 115 registry = LocateRegistry.createRegistry(getRegistryPort()); 116 } 117 catch (Exception e) { 118 log("Could not get or create RMI registry on port " + 119 getRegistryPort() + ": " + e.getMessage()); 120 return; 121 } 122 } 123 124 // If we get here, we must have a valid registry. 125 // Now register this servlet instance with that registry. 126 try { 127 registry.rebind(getRegistryName(), this); 128 } 129 catch (Exception e) { 130 log("humbug Could not bind to RMI registry: " + e.getMessage()); 131 return; 132 } 133 } 134 135 /** 136 * Unbinds the servlet from the registry. 137 * Logs any errors. 138 */ 139 protected void unbind() { 140 try { 141 if (registry != null) registry.unbind(getRegistryName()); 142 } 143 catch (Exception e) { 144 log("Problem unbinding from RMI registry: " + e.getMessage()); 145 } 146 } 147 148}