1 /*
   2  * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.corba.se.impl.activation;
  27 
  28 /**
  29  *
  30  * @author      Rohit Garg
  31  * @author      Ken Cavanaugh
  32  * @author      Hemanth Puttaswamy
  33  * @since       JDK1.2
  34  */
  35 
  36 import java.lang.reflect.Constructor;
  37 import java.util.ArrayList;
  38 import java.util.HashMap;
  39 import java.util.Iterator;
  40 import java.util.NoSuchElementException;
  41 
  42 import org.omg.CORBA.OBJECT_NOT_EXIST;
  43 import org.omg.CORBA.SystemException;
  44 
  45 import com.sun.corba.se.spi.activation.EndPointInfo;
  46 import com.sun.corba.se.spi.activation.IIOP_CLEAR_TEXT;
  47 import com.sun.corba.se.spi.activation.ORBPortInfo;
  48 import com.sun.corba.se.spi.activation.Repository;
  49 import com.sun.corba.se.spi.activation.LocatorPackage.ServerLocation;
  50 import com.sun.corba.se.spi.activation.LocatorPackage.ServerLocationPerORB;
  51 import com.sun.corba.se.spi.activation.RepositoryPackage.ServerDef;
  52 import com.sun.corba.se.spi.activation._ServerManagerImplBase;
  53 import com.sun.corba.se.spi.activation.ServerAlreadyActive;
  54 import com.sun.corba.se.spi.activation.ServerAlreadyInstalled;
  55 import com.sun.corba.se.spi.activation.ServerAlreadyUninstalled;
  56 import com.sun.corba.se.spi.activation.ServerNotRegistered;
  57 import com.sun.corba.se.spi.activation.ORBAlreadyRegistered;
  58 import com.sun.corba.se.spi.activation.ServerHeldDown;
  59 import com.sun.corba.se.spi.activation.ServerNotActive;
  60 import com.sun.corba.se.spi.activation.NoSuchEndPoint;
  61 import com.sun.corba.se.spi.activation.InvalidORBid;
  62 import com.sun.corba.se.spi.activation.Server;
  63 import com.sun.corba.se.spi.activation.IIOP_CLEAR_TEXT;
  64 import com.sun.corba.se.spi.ior.IORTemplate ;
  65 import com.sun.corba.se.spi.ior.IOR ;
  66 import com.sun.corba.se.spi.ior.ObjectKey ;
  67 import com.sun.corba.se.spi.ior.ObjectKeyTemplate ;
  68 import com.sun.corba.se.spi.ior.IORFactories ;
  69 import com.sun.corba.se.spi.ior.iiop.GIOPVersion ;
  70 import com.sun.corba.se.spi.ior.iiop.IIOPAddress ;
  71 import com.sun.corba.se.spi.ior.iiop.IIOPProfileTemplate ;
  72 import com.sun.corba.se.spi.ior.iiop.IIOPFactories ;
  73 import com.sun.corba.se.spi.legacy.connection.LegacyServerSocketEndPointInfo;
  74 import com.sun.corba.se.spi.transport.SocketOrChannelAcceptor;
  75 import com.sun.corba.se.spi.orb.ORB ;
  76 import com.sun.corba.se.spi.protocol.ForwardException;
  77 import com.sun.corba.se.spi.transport.CorbaTransportManager;
  78 
  79 import com.sun.corba.se.spi.logging.CORBALogDomains ;
  80 import com.sun.corba.se.impl.logging.ActivationSystemException ;
  81 
  82 import com.sun.corba.se.impl.oa.poa.BadServerIdHandler;
  83 import com.sun.corba.se.impl.orbutil.ORBConstants;
  84 import com.sun.corba.se.impl.orbutil.ORBUtility;
  85 import com.sun.corba.se.impl.util.Utility;
  86 
  87 public class ServerManagerImpl extends _ServerManagerImplBase
  88     implements BadServerIdHandler
  89 {
  90     // Using HashMap, since synchronization should be done by the calling
  91     // routines
  92     HashMap serverTable;
  93     Repository repository;
  94 
  95     CorbaTransportManager transportManager;
  96     int initialPort;
  97     ORB orb;
  98     ActivationSystemException wrapper;
  99     String dbDirName;
 100     boolean debug = false ;
 101 
 102     private int serverStartupDelay;
 103 
 104     ServerManagerImpl(ORB orb, CorbaTransportManager transportManager,
 105                       Repository repository, String dbDirName, boolean debug)
 106     {
 107         this.orb = orb;
 108         wrapper = ActivationSystemException.get( orb, CORBALogDomains.ORBD_ACTIVATOR ) ;
 109 
 110         this.transportManager = transportManager; // REVISIT - NOT USED.
 111         this.repository = repository;
 112         this.dbDirName = dbDirName;
 113         this.debug = debug ;
 114 
 115         LegacyServerSocketEndPointInfo endpoint =
 116             orb.getLegacyServerSocketManager()
 117                 .legacyGetEndpoint(LegacyServerSocketEndPointInfo.BOOT_NAMING);
 118 
 119         initialPort = ((SocketOrChannelAcceptor)endpoint)
 120             .getServerSocket().getLocalPort();
 121         serverTable = new HashMap(256);
 122 
 123         // The ServerStartupDelay is the delay added after the Server registers
 124         // end point information. This is to allow the server to completely
 125         // initialize after ORB is instantiated.
 126         serverStartupDelay = ORBConstants.DEFAULT_SERVER_STARTUP_DELAY;
 127         String  delay = System.getProperty( ORBConstants.SERVER_STARTUP_DELAY);
 128         if( delay != null ) {
 129             try {
 130                 serverStartupDelay = Integer.parseInt( delay );
 131             } catch ( Exception e ) {
 132                 // Just use the default 1000 milliseconds as the default
 133             }
 134         }
 135 
 136         Class cls = orb.getORBData( ).getBadServerIdHandler();
 137         if( cls == null ) {
 138             orb.setBadServerIdHandler( this );
 139         } else {
 140             orb.initBadServerIdHandler() ;
 141         }
 142 
 143         orb.connect(this);
 144         ProcessMonitorThread.start( serverTable );
 145     }
 146 
 147     public void activate(int serverId)
 148         throws ServerAlreadyActive, ServerNotRegistered, ServerHeldDown
 149     {
 150 
 151         ServerLocation   location;
 152         ServerTableEntry entry;
 153         Integer key = new Integer(serverId);
 154 
 155         synchronized(serverTable) {
 156             entry = (ServerTableEntry) serverTable.get(key);
 157         }
 158 
 159         if (entry != null && entry.isActive()) {
 160             if (debug)
 161                 System.out.println( "ServerManagerImpl: activate for server Id " +
 162                                     serverId + " failed because server is already active. " +
 163                                     "entry = " + entry ) ;
 164 
 165             throw new ServerAlreadyActive( serverId );
 166         }
 167 
 168         // locate the server
 169         try {
 170 
 171             // We call getEntry here so that state of the entry is
 172             // checked for validity before we actually go and locate a server
 173 
 174             entry = getEntry(serverId);
 175 
 176             if (debug)
 177                 System.out.println( "ServerManagerImpl: locateServer called with " +
 178                                 " serverId=" + serverId + " endpointType="
 179                                 + IIOP_CLEAR_TEXT.value + " block=false" ) ;
 180 
 181             location = locateServer(entry, IIOP_CLEAR_TEXT.value, false);
 182 
 183             if (debug)
 184                 System.out.println( "ServerManagerImpl: activate for server Id " +
 185                                     serverId + " found location " +
 186                                     location.hostname + " and activated it" ) ;
 187         } catch (NoSuchEndPoint ex) {
 188             if (debug)
 189                 System.out.println( "ServerManagerImpl: activate for server Id " +
 190                                     " threw NoSuchEndpoint exception, which was ignored" );
 191         }
 192     }
 193 
 194     public void active(int serverId, Server server) throws ServerNotRegistered
 195     {
 196         ServerTableEntry entry;
 197         Integer key = new Integer(serverId);
 198 
 199         synchronized (serverTable) {
 200             entry = (ServerTableEntry) serverTable.get(key);
 201 
 202             if (entry == null) {
 203                 if (debug)
 204                     System.out.println( "ServerManagerImpl: active for server Id " +
 205                                         serverId + " called, but no such server is registered." ) ;
 206 
 207                 throw wrapper.serverNotExpectedToRegister() ;
 208             } else {
 209                 if (debug)
 210                     System.out.println( "ServerManagerImpl: active for server Id " +
 211                                         serverId + " called.  This server is now active." ) ;
 212 
 213                 entry.register(server);
 214             }
 215         }
 216     }
 217 
 218     public void registerEndpoints( int serverId, String orbId,
 219         EndPointInfo [] endpointList ) throws NoSuchEndPoint, ServerNotRegistered,
 220         ORBAlreadyRegistered
 221     {
 222         // orbId is ignored for now
 223         ServerTableEntry entry;
 224         Integer key = new Integer(serverId);
 225 
 226         synchronized (serverTable) {
 227             entry = (ServerTableEntry) serverTable.get(key);
 228 
 229             if (entry == null) {
 230                 if (debug)
 231                     System.out.println(
 232                         "ServerManagerImpl: registerEndpoint for server Id " +
 233                         serverId + " called, but no such server is registered." ) ;
 234 
 235                 throw wrapper.serverNotExpectedToRegister() ;
 236             } else {
 237                 if (debug)
 238                     System.out.println(
 239                         "ServerManagerImpl: registerEndpoints for server Id " +
 240                         serverId + " called.  This server is now active." ) ;
 241 
 242                 entry.registerPorts( orbId, endpointList );
 243 
 244             }
 245         }
 246     }
 247 
 248     public int[] getActiveServers()
 249     {
 250         ServerTableEntry entry;
 251         int[] list = null;
 252 
 253         synchronized (serverTable) {
 254             // unlike vectors, list is not synchronized
 255 
 256             ArrayList servers = new ArrayList(0);
 257 
 258             Iterator serverList = serverTable.keySet().iterator();
 259 
 260             try {
 261                 while (serverList.hasNext()) {
 262                     Integer key = (Integer) serverList.next();
 263                     // get an entry
 264                     entry = (ServerTableEntry) serverTable.get(key);
 265 
 266                     if (entry.isValid() && entry.isActive()) {
 267                         servers.add(entry);
 268                     }
 269                 }
 270             } catch (NoSuchElementException e) {
 271                 // all done
 272             }
 273 
 274             // collect the active entries
 275             list = new int[servers.size()];
 276             for (int i = 0; i < servers.size(); i++) {
 277                 entry = (ServerTableEntry) servers.get(i);
 278                 list[i] = entry.getServerId();
 279             }
 280         }
 281 
 282         if (debug) {
 283             StringBuffer sb = new StringBuffer() ;
 284             for (int ctr=0; ctr<list.length; ctr++) {
 285                 sb.append( ' ' ) ;
 286                 sb.append( list[ctr] ) ;
 287             }
 288 
 289             System.out.println( "ServerManagerImpl: getActiveServers returns" +
 290                                 sb.toString() ) ;
 291         }
 292 
 293         return list;
 294     }
 295 
 296     public void shutdown(int serverId) throws ServerNotActive
 297     {
 298         ServerTableEntry entry;
 299         Integer key = new Integer(serverId);
 300 
 301         synchronized(serverTable) {
 302             entry = (ServerTableEntry) serverTable.remove(key);
 303 
 304             if (entry == null) {
 305                 if (debug)
 306                     System.out.println( "ServerManagerImpl: shutdown for server Id " +
 307                                     serverId + " throws ServerNotActive." ) ;
 308 
 309                 throw new ServerNotActive( serverId );
 310             }
 311 
 312             try {
 313                 entry.destroy();
 314 
 315                 if (debug)
 316                     System.out.println( "ServerManagerImpl: shutdown for server Id " +
 317                                     serverId + " completed." ) ;
 318             } catch (Exception e) {
 319                 if (debug)
 320                     System.out.println( "ServerManagerImpl: shutdown for server Id " +
 321                                     serverId + " threw exception " + e ) ;
 322             }
 323         }
 324     }
 325 
 326     private ServerTableEntry getEntry( int serverId )
 327         throws ServerNotRegistered
 328     {
 329         Integer key = new Integer(serverId);
 330         ServerTableEntry entry = null ;
 331 
 332         synchronized (serverTable) {
 333             entry = (ServerTableEntry) serverTable.get(key);
 334 
 335             if (debug)
 336                 if (entry == null) {
 337                     System.out.println( "ServerManagerImpl: getEntry: " +
 338                                         "no active server found." ) ;
 339                 } else {
 340                     System.out.println( "ServerManagerImpl: getEntry: " +
 341                                         " active server found " + entry + "." ) ;
 342                 }
 343 
 344             if ((entry != null) && (!entry.isValid())) {
 345                 serverTable.remove(key);
 346                 entry = null;
 347             }
 348 
 349             if (entry == null) {
 350                 ServerDef serverDef = repository.getServer(serverId);
 351 
 352                 entry = new ServerTableEntry( wrapper,
 353                     serverId, serverDef, initialPort, dbDirName, false, debug);
 354                 serverTable.put(key, entry);
 355                 entry.activate() ;
 356             }
 357         }
 358 
 359         return entry ;
 360     }
 361 
 362     private ServerLocation locateServer (ServerTableEntry entry, String endpointType,
 363                                         boolean block)
 364         throws NoSuchEndPoint, ServerNotRegistered, ServerHeldDown
 365     {
 366         ServerLocation location = new ServerLocation() ;
 367 
 368         // if server location is desired, then wait for the server
 369         // to register back, then return location
 370 
 371         ORBPortInfo [] serverORBAndPortList;
 372         if (block) {
 373             try {
 374                     serverORBAndPortList = entry.lookup(endpointType);
 375             } catch (Exception ex) {
 376                 if (debug)
 377                     System.out.println( "ServerManagerImpl: locateServer: " +
 378                                         "server held down" ) ;
 379 
 380                 throw new ServerHeldDown( entry.getServerId() );
 381             }
 382 
 383             String host =
 384                 orb.getLegacyServerSocketManager()
 385                     .legacyGetEndpoint(LegacyServerSocketEndPointInfo.DEFAULT_ENDPOINT).getHostName();
 386             location.hostname = host ;
 387             int listLength;
 388             if (serverORBAndPortList != null) {
 389                 listLength = serverORBAndPortList.length;
 390             } else {
 391                 listLength = 0;
 392             }
 393             location.ports = new ORBPortInfo[listLength];
 394             for (int i = 0; i < listLength; i++) {
 395                 location.ports[i] = new ORBPortInfo(serverORBAndPortList[i].orbId,
 396                         serverORBAndPortList[i].port) ;
 397 
 398                 if (debug)
 399                     System.out.println( "ServerManagerImpl: locateServer: " +
 400                                     "server located at location " +
 401                                     location.hostname + " ORBid  " +
 402                                     serverORBAndPortList[i].orbId +
 403                                     " Port " + serverORBAndPortList[i].port) ;
 404             }
 405         }
 406 
 407         return location;
 408     }
 409 
 410     private ServerLocationPerORB locateServerForORB (ServerTableEntry entry, String orbId,
 411                                         boolean block)
 412         throws InvalidORBid, ServerNotRegistered, ServerHeldDown
 413     {
 414         ServerLocationPerORB location = new ServerLocationPerORB() ;
 415 
 416         // if server location is desired, then wait for the server
 417         // to register back, then return location
 418 
 419         EndPointInfo [] endpointInfoList;
 420         if (block) {
 421             try {
 422                 endpointInfoList = entry.lookupForORB(orbId);
 423             } catch (InvalidORBid ex) {
 424                 throw ex;
 425             } catch (Exception ex) {
 426                 if (debug)
 427                     System.out.println( "ServerManagerImpl: locateServerForORB: " +
 428                                         "server held down" ) ;
 429 
 430                 throw new ServerHeldDown( entry.getServerId() );
 431             }
 432 
 433             String host =
 434                 orb.getLegacyServerSocketManager()
 435                     .legacyGetEndpoint(LegacyServerSocketEndPointInfo.DEFAULT_ENDPOINT).getHostName();
 436             location.hostname = host ;
 437             int listLength;
 438             if (endpointInfoList != null) {
 439                 listLength = endpointInfoList.length;
 440             } else {
 441                 listLength = 0;
 442             }
 443             location.ports = new EndPointInfo[listLength];
 444             for (int i = 0; i < listLength; i++) {
 445                 location.ports[i] = new EndPointInfo(endpointInfoList[i].endpointType,
 446                         endpointInfoList[i].port) ;
 447 
 448                 if (debug)
 449                     System.out.println( "ServerManagerImpl: locateServer: " +
 450                                     "server located at location " +
 451                                     location.hostname + " endpointType  " +
 452                                     endpointInfoList[i].endpointType +
 453                                     " Port " + endpointInfoList[i].port) ;
 454             }
 455         }
 456 
 457         return location;
 458     }
 459 
 460     public String[] getORBNames(int serverId)
 461         throws ServerNotRegistered
 462     {
 463         try {
 464             ServerTableEntry entry = getEntry( serverId ) ;
 465             return (entry.getORBList());
 466         } catch (Exception ex) {
 467             throw new ServerNotRegistered(serverId);
 468         }
 469     }
 470 
 471     private ServerTableEntry getRunningEntry( int serverId )
 472         throws ServerNotRegistered
 473     {
 474         ServerTableEntry entry = getEntry( serverId ) ;
 475 
 476         try {
 477             // this is to see if the server has any listeners
 478             ORBPortInfo [] serverORBAndPortList = entry.lookup(IIOP_CLEAR_TEXT.value) ;
 479         } catch (Exception exc) {
 480             return null ;
 481         }
 482         return entry;
 483 
 484     }
 485 
 486     public void install( int serverId )
 487         throws ServerNotRegistered, ServerHeldDown, ServerAlreadyInstalled
 488     {
 489         ServerTableEntry entry = getRunningEntry( serverId ) ;
 490         if (entry != null) {
 491             repository.install( serverId ) ;
 492             entry.install() ;
 493         }
 494     }
 495 
 496     public void uninstall( int serverId )
 497         throws ServerNotRegistered, ServerHeldDown, ServerAlreadyUninstalled
 498     {
 499         ServerTableEntry entry =
 500             (ServerTableEntry) serverTable.get( new Integer(serverId) );
 501 
 502         if (entry != null) {
 503 
 504             entry =
 505                 (ServerTableEntry) serverTable.remove(new Integer(serverId));
 506 
 507             if (entry == null) {
 508                 if (debug)
 509                     System.out.println( "ServerManagerImpl: shutdown for server Id " +
 510                                     serverId + " throws ServerNotActive." ) ;
 511 
 512                 throw new ServerHeldDown( serverId );
 513             }
 514 
 515             entry.uninstall();
 516         }
 517     }
 518 
 519     public ServerLocation locateServer (int serverId, String endpointType)
 520         throws NoSuchEndPoint, ServerNotRegistered, ServerHeldDown
 521     {
 522         ServerTableEntry entry = getEntry( serverId ) ;
 523         if (debug)
 524             System.out.println( "ServerManagerImpl: locateServer called with " +
 525                                 " serverId=" + serverId + " endpointType=" +
 526                                 endpointType + " block=true" ) ;
 527 
 528         // passing in entry to eliminate multiple lookups for
 529         // the same entry in some cases
 530 
 531         return locateServer(entry, endpointType, true);
 532     }
 533 
 534     /** This method is used to obtain the registered ports for an ORB.
 535     * This is useful for custom Bad server ID handlers in ORBD.
 536     */
 537     public ServerLocationPerORB locateServerForORB (int serverId, String orbId)
 538         throws InvalidORBid, ServerNotRegistered, ServerHeldDown
 539     {
 540         ServerTableEntry entry = getEntry( serverId ) ;
 541 
 542         // passing in entry to eliminate multiple lookups for
 543         // the same entry in some cases
 544 
 545         if (debug)
 546             System.out.println( "ServerManagerImpl: locateServerForORB called with " +
 547                                 " serverId=" + serverId + " orbId=" + orbId +
 548                                 " block=true" ) ;
 549         return locateServerForORB(entry, orbId, true);
 550     }
 551 
 552 
 553     public void handle(ObjectKey okey)
 554     {
 555         IOR newIOR = null;
 556         ServerLocationPerORB location;
 557 
 558         // we need to get the serverid and the orbid from the object key
 559         ObjectKeyTemplate oktemp = okey.getTemplate();
 560         int serverId = oktemp.getServerId() ;
 561         String orbId = oktemp.getORBId() ;
 562 
 563         try {
 564             // get the ORBName corresponding to the orbMapid, that was
 565             // first registered by the server
 566             ServerTableEntry entry = getEntry( serverId ) ;
 567             location = locateServerForORB(entry, orbId, true);
 568 
 569             if (debug)
 570                 System.out.println( "ServerManagerImpl: handle called for server id" +
 571                         serverId + "  orbid  " + orbId) ;
 572 
 573             // we received a list of ports corresponding to an ORB in a
 574             // particular server, now retrieve the one corresponding
 575             // to IIOP_CLEAR_TEXT, and for other created the tagged
 576             // components to be added to the IOR
 577 
 578             int clearPort = 0;
 579             EndPointInfo[] listenerPorts = location.ports;
 580             for (int i = 0; i < listenerPorts.length; i++) {
 581                 if ((listenerPorts[i].endpointType).equals(IIOP_CLEAR_TEXT.value)) {
 582                     clearPort = listenerPorts[i].port;
 583                     break;
 584                 }
 585             }
 586 
 587             // create a new IOR with the correct port and correct tagged
 588             // components
 589             IIOPAddress addr = IIOPFactories.makeIIOPAddress( orb,
 590                 location.hostname, clearPort ) ;
 591             IIOPProfileTemplate iptemp =
 592                 IIOPFactories.makeIIOPProfileTemplate(
 593                     orb, GIOPVersion.V1_2, addr ) ;
 594             if (GIOPVersion.V1_2.supportsIORIIOPProfileComponents()) {
 595                 iptemp.add(IIOPFactories.makeCodeSetsComponent(orb));
 596                 iptemp.add(IIOPFactories.makeMaxStreamFormatVersionComponent());
 597             }
 598             IORTemplate iortemp = IORFactories.makeIORTemplate(oktemp) ;
 599             iortemp.add( iptemp ) ;
 600 
 601             newIOR = iortemp.makeIOR(orb, "IDL:org/omg/CORBA/Object:1.0",
 602                 okey.getId() );
 603         } catch (Exception e) {
 604             throw wrapper.errorInBadServerIdHandler( e ) ;
 605         }
 606 
 607         if (debug)
 608             System.out.println( "ServerManagerImpl: handle " +
 609                                 "throws ForwardException" ) ;
 610 
 611 
 612         try {
 613             // This delay is required in case of Server is activated or
 614             // re-activated the first time. Server needs some time before
 615             // handling all the requests.
 616             // (Talk to Ken to see whether there is a better way of doing this).
 617             Thread.sleep( serverStartupDelay );
 618         } catch ( Exception e ) {
 619             System.out.println( "Exception = " + e );
 620             e.printStackTrace();
 621         }
 622 
 623         throw new ForwardException(orb, newIOR);
 624     }
 625 
 626     public int getEndpoint(String endpointType) throws NoSuchEndPoint
 627     {
 628         return orb.getLegacyServerSocketManager()
 629             .legacyGetTransientServerPort(endpointType);
 630     }
 631 
 632     public int getServerPortForType(ServerLocationPerORB location,
 633                                     String endPointType)
 634         throws NoSuchEndPoint
 635     {
 636         EndPointInfo[] listenerPorts = location.ports;
 637         for (int i = 0; i < listenerPorts.length; i++) {
 638             if ((listenerPorts[i].endpointType).equals(endPointType)) {
 639                 return listenerPorts[i].port;
 640             }
 641         }
 642         throw new NoSuchEndPoint();
 643     }
 644 
 645 }