/** Unbind the RMI service from the registry on bean factory shutdown. */
 public void destroy() throws RemoteException {
   if (logger.isInfoEnabled()) {
     logger.info(
         "Unbinding RMI service '"
             + this.serviceName
             + "' from registry at port '"
             + this.registryPort
             + "'");
   }
   try {
     this.registry.unbind(this.serviceName);
   } catch (NotBoundException ex) {
     if (logger.isWarnEnabled()) {
       logger.warn(
           "RMI service '"
               + this.serviceName
               + "' is not bound to registry at port '"
               + this.registryPort
               + "' anymore",
           ex);
     }
   } finally {
     unexportObjectSilently();
   }
 }
  /**
   * Initialize this service exporter, registering the service as RMI object.
   *
   * <p>Creates an RMI registry on the specified port if none exists.
   *
   * @throws RemoteException if service registration failed
   */
  public void prepare() throws RemoteException {
    checkService();

    if (this.serviceName == null) {
      throw new IllegalArgumentException("Property 'serviceName' is required");
    }

    // Check socket factories for exported object.
    if (this.clientSocketFactory instanceof RMIServerSocketFactory) {
      this.serverSocketFactory = (RMIServerSocketFactory) this.clientSocketFactory;
    }
    if ((this.clientSocketFactory != null && this.serverSocketFactory == null)
        || (this.clientSocketFactory == null && this.serverSocketFactory != null)) {
      throw new IllegalArgumentException(
          "Both RMIClientSocketFactory and RMIServerSocketFactory or none required");
    }

    // Check socket factories for RMI registry.
    if (this.registryClientSocketFactory instanceof RMIServerSocketFactory) {
      this.registryServerSocketFactory = (RMIServerSocketFactory) this.registryClientSocketFactory;
    }
    if (this.registryClientSocketFactory == null && this.registryServerSocketFactory != null) {
      throw new IllegalArgumentException(
          "RMIServerSocketFactory without RMIClientSocketFactory for registry not supported");
    }

    // Determine RMI registry to use.
    if (this.registry == null) {
      this.registry =
          getRegistry(
              this.registryHost,
              this.registryPort,
              this.registryClientSocketFactory,
              this.registryServerSocketFactory);
    }

    // Initialize and cache exported object.
    this.exportedObject = getObjectToExport();

    if (logger.isInfoEnabled()) {
      logger.info("Binding service '" + this.serviceName + "' to RMI registry: " + this.registry);
    }

    // Export RMI object.
    if (this.clientSocketFactory != null) {
      UnicastRemoteObject.exportObject(
          this.exportedObject,
          this.servicePort,
          this.clientSocketFactory,
          this.serverSocketFactory);
    } else {
      UnicastRemoteObject.exportObject(this.exportedObject, this.servicePort);
    }

    // Bind RMI object to registry.
    try {
      if (this.replaceExistingBinding) {
        this.registry.rebind(this.serviceName, this.exportedObject);
      } else {
        this.registry.bind(this.serviceName, this.exportedObject);
      }
    } catch (AlreadyBoundException ex) {
      // Already an RMI object bound for the specified service name...
      unexportObjectSilently();
      throw new IllegalStateException(
          "Already an RMI object bound for name '" + this.serviceName + "': " + ex.toString());
    } catch (RemoteException ex) {
      // Registry binding failed: let's unexport the RMI object as well.
      unexportObjectSilently();
      throw ex;
    }
  }