1 /*
   2  * Copyright (c) 2002, 2014, 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.spi.orb;
  27 
  28 import java.util.Map ;
  29 import java.util.HashMap ;
  30 import java.util.Properties ;
  31 import java.util.concurrent.ConcurrentHashMap;
  32 import java.util.logging.Logger ;
  33 
  34 import java.security.AccessController ;
  35 import java.security.PrivilegedAction ;
  36 
  37 import org.omg.CORBA.TCKind ;
  38 
  39 import com.sun.corba.se.pept.broker.Broker ;
  40 import com.sun.corba.se.pept.transport.ByteBufferPool;
  41 
  42 import com.sun.corba.se.spi.protocol.RequestDispatcherRegistry ;
  43 import com.sun.corba.se.spi.protocol.ClientDelegateFactory ;
  44 import com.sun.corba.se.spi.protocol.CorbaServerRequestDispatcher ;
  45 import com.sun.corba.se.spi.protocol.CorbaMessageMediator ;
  46 import com.sun.corba.se.spi.protocol.PIHandler ;
  47 import com.sun.corba.se.spi.resolver.LocalResolver ;
  48 import com.sun.corba.se.spi.resolver.Resolver ;
  49 import com.sun.corba.se.spi.transport.CorbaContactInfoListFactory ;
  50 import com.sun.corba.se.spi.legacy.connection.LegacyServerSocketEndPointInfo;
  51 import com.sun.corba.se.spi.legacy.connection.LegacyServerSocketManager;
  52 import com.sun.corba.se.spi.monitoring.MonitoringConstants;
  53 import com.sun.corba.se.spi.monitoring.MonitoringManager;
  54 import com.sun.corba.se.spi.monitoring.MonitoringManagerFactory;
  55 import com.sun.corba.se.spi.monitoring.MonitoringFactories;
  56 
  57 import com.sun.corba.se.spi.ior.IdentifiableFactoryFinder ;
  58 import com.sun.corba.se.spi.ior.TaggedComponentFactoryFinder ;
  59 import com.sun.corba.se.spi.ior.ObjectKey ;
  60 import com.sun.corba.se.spi.ior.ObjectKeyFactory ;
  61 import com.sun.corba.se.spi.ior.IOR ;
  62 
  63 import com.sun.corba.se.spi.orbutil.closure.Closure ;
  64 
  65 import com.sun.corba.se.spi.orb.Operation ;
  66 import com.sun.corba.se.spi.orb.ORBData ;
  67 import com.sun.corba.se.spi.orb.ORBVersion ;
  68 import com.sun.corba.se.spi.orbutil.threadpool.ThreadPoolManager;
  69 
  70 import com.sun.corba.se.spi.oa.OAInvocationInfo ;
  71 import com.sun.corba.se.spi.transport.CorbaTransportManager;
  72 
  73 import com.sun.corba.se.spi.logging.LogWrapperFactory ;
  74 import com.sun.corba.se.spi.logging.LogWrapperBase ;
  75 import com.sun.corba.se.spi.logging.CORBALogDomains ;
  76 
  77 import com.sun.corba.se.spi.copyobject.CopierManager ;
  78 
  79 import com.sun.corba.se.spi.presentation.rmi.PresentationManager ;
  80 import com.sun.corba.se.spi.presentation.rmi.PresentationDefaults ;
  81 
  82 import com.sun.corba.se.spi.servicecontext.ServiceContextRegistry ;
  83 
  84 // XXX needs an SPI or else it does not belong here
  85 import com.sun.corba.se.impl.corba.TypeCodeImpl ;
  86 import com.sun.corba.se.impl.corba.TypeCodeFactory ;
  87 
  88 // XXX Should there be a SPI level constants ?
  89 import com.sun.corba.se.impl.orbutil.ORBConstants ;
  90 
  91 import com.sun.corba.se.impl.oa.poa.BadServerIdHandler ;
  92 
  93 import com.sun.corba.se.impl.transport.ByteBufferPoolImpl;
  94 
  95 import com.sun.corba.se.impl.logging.ORBUtilSystemException ;
  96 import com.sun.corba.se.impl.logging.OMGSystemException ;
  97 
  98 import com.sun.corba.se.impl.presentation.rmi.PresentationManagerImpl ;
  99 
 100 import sun.awt.AppContext;
 101 import sun.corba.SharedSecrets;
 102 
 103 public abstract class ORB extends com.sun.corba.se.org.omg.CORBA.ORB
 104     implements Broker, TypeCodeFactory
 105 {
 106     // As much as possible, this class should be stateless.  However,
 107     // there are a few reasons why it is not:
 108     //
 109     // 1. The ORB debug flags are defined here because they are accessed
 110     //    frequently, and we do not want a cast to the impl just for that.
 111     // 2. typeCodeMap and primitiveTypeCodeConstants are here because they
 112     //    are needed in both ORBImpl and ORBSingleton.
 113     // 3. Logging support is here so that we can avoid problems with
 114     //    incompletely initialized ORBs that need to perform logging.
 115 
 116     // Flag set at compile time to debug flag processing: this can't
 117     // be one of the xxxDebugFlags because it is used to debug the mechanism
 118     // that sets the xxxDebugFlags!
 119     public static boolean ORBInitDebug = false;
 120 
 121     // Currently defined debug flags.  Any additions must be called xxxDebugFlag.
 122     // All debug flags must be public boolean types.
 123     // These are set by passing the flag -ORBDebug x,y,z in the ORB init args.
 124     // Note that x,y,z must not contain spaces.
 125     public boolean transportDebugFlag = false ;
 126     public boolean subcontractDebugFlag = false ;
 127     public boolean poaDebugFlag = false ;
 128     public boolean poaConcurrencyDebugFlag = false ;
 129     public boolean poaFSMDebugFlag = false ;
 130     public boolean orbdDebugFlag = false ;
 131     public boolean namingDebugFlag = false ;
 132     public boolean serviceContextDebugFlag = false ;
 133     public boolean transientObjectManagerDebugFlag = false ;
 134     public boolean giopVersionDebugFlag = false;
 135     public boolean shutdownDebugFlag = false;
 136     public boolean giopDebugFlag = false;
 137     public boolean invocationTimingDebugFlag = false ;
 138 
 139     // SystemException log wrappers.  Protected so that they can be used in
 140     // subclasses.
 141     protected static ORBUtilSystemException staticWrapper ;
 142     protected ORBUtilSystemException wrapper ;
 143     protected OMGSystemException omgWrapper ;
 144 
 145     // This map is needed for resolving recursive type code placeholders
 146     // based on the unique repository id.
 147     // XXX Should this be a WeakHashMap for GC?
 148     private Map typeCodeMap ;
 149 
 150     private TypeCodeImpl[] primitiveTypeCodeConstants ;
 151 
 152     // ByteBufferPool - needed by both ORBImpl and ORBSingleton
 153     ByteBufferPool byteBufferPool;
 154 
 155     // Local testing
 156     // XXX clean this up, probably remove these
 157     public abstract boolean isLocalHost( String hostName ) ;
 158     public abstract boolean isLocalServerId( int subcontractId, int serverId ) ;
 159 
 160     // Invocation stack manipulation
 161     public abstract OAInvocationInfo peekInvocationInfo() ;
 162     public abstract void pushInvocationInfo( OAInvocationInfo info ) ;
 163     public abstract OAInvocationInfo popInvocationInfo() ;
 164 
 165     public abstract CorbaTransportManager getCorbaTransportManager();
 166     public abstract LegacyServerSocketManager getLegacyServerSocketManager();
 167 
 168     // wrapperMap maintains a table of LogWrapper instances used by
 169     // different classes to log exceptions.  The key is a StringPair
 170     // representing LogDomain and ExceptionGroup.
 171     private Map wrapperMap ;
 172 
 173     static class Holder {
 174         static final PresentationManager defaultPresentationManager =
 175             setupPresentationManager();
 176     }
 177     private static final Object pmLock = new Object();
 178 
 179     private static Map staticWrapperMap = new ConcurrentHashMap();
 180 
 181     protected MonitoringManager monitoringManager;
 182 
 183     private static PresentationManager setupPresentationManager() {
 184         staticWrapper = ORBUtilSystemException.get(
 185             CORBALogDomains.RPC_PRESENTATION ) ;
 186 
 187         boolean useDynamicStub =
 188             ((Boolean)AccessController.doPrivileged(
 189                 new PrivilegedAction() {
 190                     public java.lang.Object run() {
 191                         return Boolean.valueOf( Boolean.getBoolean (
 192                             ORBConstants.USE_DYNAMIC_STUB_PROPERTY ) ) ;
 193                     }
 194                 }
 195             )).booleanValue() ;
 196 
 197         PresentationManager.StubFactoryFactory dynamicStubFactoryFactory =
 198             (PresentationManager.StubFactoryFactory)AccessController.doPrivileged(
 199                 new PrivilegedAction() {
 200                     public java.lang.Object run() {
 201                         PresentationManager.StubFactoryFactory sff =
 202                             PresentationDefaults.getProxyStubFactoryFactory() ;
 203 
 204                         String className = System.getProperty(
 205                             ORBConstants.DYNAMIC_STUB_FACTORY_FACTORY_CLASS,
 206                             "com.sun.corba.se.impl.presentation.rmi.bcel.StubFactoryFactoryBCELImpl" ) ;
 207 
 208                         try {
 209                             // First try the configured class name, if any
 210                             Class<?> cls = SharedSecrets.getJavaCorbaAccess().loadClass( className ) ;
 211                             sff = (PresentationManager.StubFactoryFactory)cls.newInstance() ;
 212                         } catch (Exception exc) {
 213                             // Use the default. Log the error as a warning.
 214                             staticWrapper.errorInSettingDynamicStubFactoryFactory(
 215                                 exc, className ) ;
 216                         }
 217 
 218                         return sff ;
 219                     }
 220                 }
 221             ) ;
 222 
 223         PresentationManager pm = new PresentationManagerImpl( useDynamicStub ) ;
 224         pm.setStubFactoryFactory( false,
 225             PresentationDefaults.getStaticStubFactoryFactory() ) ;
 226         pm.setStubFactoryFactory( true, dynamicStubFactoryFactory ) ;
 227         return pm;
 228     }
 229 
 230     public void destroy() {
 231         wrapper = null;
 232         omgWrapper = null;
 233         typeCodeMap = null;
 234         primitiveTypeCodeConstants = null;
 235         byteBufferPool = null;
 236     }
 237 
 238     /**
 239      * Returns the Presentation Manager for the current thread group, using the ThreadGroup-specific
 240      * AppContext to hold it. Creates and records one if needed.
 241      */
 242     public static PresentationManager getPresentationManager()
 243     {
 244         SecurityManager sm = System.getSecurityManager();
 245         if (sm != null && AppContext.getAppContexts().size() > 0) {
 246             AppContext ac = AppContext.getAppContext();
 247             if (ac != null) {
 248                 synchronized (pmLock) {
 249                     PresentationManager pm = 
 250                         (PresentationManager) ac.get(PresentationManager.class);
 251                     if (pm == null) {
 252                         pm = setupPresentationManager();
 253                         ac.put(PresentationManager.class, pm);
 254                     }
 255                     return pm;
 256                 }
 257             }
 258         }
 259 
 260         // No security manager or AppContext
 261         return Holder.defaultPresentationManager;
 262     }
 263 
 264     /** Get the appropriate StubFactoryFactory.  This
 265      * will be dynamic or static depending on whether
 266      * com.sun.CORBA.ORBUseDynamicStub is true or false.
 267      */
 268     public static PresentationManager.StubFactoryFactory
 269         getStubFactoryFactory()
 270     {
 271         PresentationManager gPM = getPresentationManager();
 272         boolean useDynamicStubs = gPM.useDynamicStubs() ;
 273         return gPM.getStubFactoryFactory( useDynamicStubs ) ;
 274     }
 275 
 276     protected ORB()
 277     {
 278         // Initialize logging first, since it is needed nearly
 279         // everywhere (for example, in TypeCodeImpl).
 280         wrapperMap = new ConcurrentHashMap();
 281         wrapper = ORBUtilSystemException.get( this,
 282             CORBALogDomains.RPC_PRESENTATION ) ;
 283         omgWrapper = OMGSystemException.get( this,
 284             CORBALogDomains.RPC_PRESENTATION ) ;
 285 
 286         typeCodeMap = new HashMap();
 287 
 288         primitiveTypeCodeConstants = new TypeCodeImpl[] {
 289             new TypeCodeImpl(this, TCKind._tk_null),
 290             new TypeCodeImpl(this, TCKind._tk_void),
 291             new TypeCodeImpl(this, TCKind._tk_short),
 292             new TypeCodeImpl(this, TCKind._tk_long),
 293             new TypeCodeImpl(this, TCKind._tk_ushort),
 294             new TypeCodeImpl(this, TCKind._tk_ulong),
 295             new TypeCodeImpl(this, TCKind._tk_float),
 296             new TypeCodeImpl(this, TCKind._tk_double),
 297             new TypeCodeImpl(this, TCKind._tk_boolean),
 298             new TypeCodeImpl(this, TCKind._tk_char),
 299             new TypeCodeImpl(this, TCKind._tk_octet),
 300             new TypeCodeImpl(this, TCKind._tk_any),
 301             new TypeCodeImpl(this, TCKind._tk_TypeCode),
 302             new TypeCodeImpl(this, TCKind._tk_Principal),
 303             new TypeCodeImpl(this, TCKind._tk_objref),
 304             null,       // tk_struct
 305             null,       // tk_union
 306             null,       // tk_enum
 307             new TypeCodeImpl(this, TCKind._tk_string),
 308             null,       // tk_sequence
 309             null,       // tk_array
 310             null,       // tk_alias
 311             null,       // tk_except
 312             new TypeCodeImpl(this, TCKind._tk_longlong),
 313             new TypeCodeImpl(this, TCKind._tk_ulonglong),
 314             new TypeCodeImpl(this, TCKind._tk_longdouble),
 315             new TypeCodeImpl(this, TCKind._tk_wchar),
 316             new TypeCodeImpl(this, TCKind._tk_wstring),
 317             new TypeCodeImpl(this, TCKind._tk_fixed),
 318             new TypeCodeImpl(this, TCKind._tk_value),
 319             new TypeCodeImpl(this, TCKind._tk_value_box),
 320             new TypeCodeImpl(this, TCKind._tk_native),
 321             new TypeCodeImpl(this, TCKind._tk_abstract_interface)
 322         } ;
 323 
 324         monitoringManager =
 325             MonitoringFactories.getMonitoringManagerFactory( ).
 326                 createMonitoringManager(
 327                 MonitoringConstants.DEFAULT_MONITORING_ROOT,
 328                 MonitoringConstants.DEFAULT_MONITORING_ROOT_DESCRIPTION);
 329     }
 330 
 331     // Typecode support: needed in both ORBImpl and ORBSingleton
 332     public TypeCodeImpl get_primitive_tc(int kind)
 333     {
 334         synchronized (this) {
 335             checkShutdownState();
 336         }
 337         try {
 338             return primitiveTypeCodeConstants[kind] ;
 339         } catch (Throwable t) {
 340             throw wrapper.invalidTypecodeKind( t, new Integer(kind) ) ;
 341         }
 342     }
 343 
 344     public synchronized void setTypeCode(String id, TypeCodeImpl code)
 345     {
 346         checkShutdownState();
 347         typeCodeMap.put(id, code);
 348     }
 349 
 350     public synchronized TypeCodeImpl getTypeCode(String id)
 351     {
 352         checkShutdownState();
 353         return (TypeCodeImpl)typeCodeMap.get(id);
 354     }
 355 
 356     public MonitoringManager getMonitoringManager( ) {
 357         synchronized (this) {
 358             checkShutdownState();
 359         }
 360         return monitoringManager;
 361     }
 362 
 363     // Special non-standard set_parameters method for
 364     // creating a precisely controlled ORB instance.
 365     // An ORB created by this call is affected only by
 366     // those properties passes explicitly in props, not by
 367     // the system properties and orb.properties files as
 368     // with the standard ORB.init methods.
 369     public abstract void set_parameters( Properties props ) ;
 370 
 371     // ORB versioning
 372     public abstract ORBVersion getORBVersion() ;
 373     public abstract void setORBVersion( ORBVersion version ) ;
 374 
 375     // XXX This needs a better name
 376     public abstract IOR getFVDCodeBaseIOR() ;
 377 
 378     /**
 379      * Handle a bad server id for the given object key.  This should
 380      * always through an exception: either a ForwardException to
 381      * allow another server to handle the request, or else an error
 382      * indication.  XXX Remove after ORT for ORBD work is integrated.
 383      */
 384     public abstract void handleBadServerId( ObjectKey okey ) ;
 385     public abstract void setBadServerIdHandler( BadServerIdHandler handler ) ;
 386     public abstract void initBadServerIdHandler() ;
 387 
 388     public abstract void notifyORB() ;
 389 
 390     public abstract PIHandler getPIHandler() ;
 391 
 392     public abstract void checkShutdownState();
 393 
 394     // Dispatch support: in the ORB because it is needed for shutdown.
 395     // This is used by the first level server side subcontract.
 396     public abstract boolean isDuringDispatch() ;
 397     public abstract void startingDispatch();
 398     public abstract void finishedDispatch();
 399 
 400     /** Return this ORB's transient server ID.  This is needed for
 401      * initializing object adapters.
 402      */
 403     public abstract int getTransientServerId();
 404 
 405     public abstract ServiceContextRegistry getServiceContextRegistry() ;
 406 
 407     public abstract RequestDispatcherRegistry getRequestDispatcherRegistry();
 408 
 409     public abstract ORBData getORBData() ;
 410 
 411     public abstract void setClientDelegateFactory( ClientDelegateFactory factory ) ;
 412 
 413     public abstract ClientDelegateFactory getClientDelegateFactory() ;
 414 
 415     public abstract void setCorbaContactInfoListFactory( CorbaContactInfoListFactory factory ) ;
 416 
 417     public abstract CorbaContactInfoListFactory getCorbaContactInfoListFactory() ;
 418 
 419     // XXX These next 7 methods should be moved to a ResolverManager.
 420 
 421     /** Set the resolver used in this ORB.  This resolver will be used for list_initial_services
 422      * and resolve_initial_references.
 423      */
 424     public abstract void setResolver( Resolver resolver ) ;
 425 
 426     /** Get the resolver used in this ORB.  This resolver will be used for list_initial_services
 427      * and resolve_initial_references.
 428      */
 429     public abstract Resolver getResolver() ;
 430 
 431     /** Set the LocalResolver used in this ORB.  This LocalResolver is used for
 432      * register_initial_reference only.
 433      */
 434     public abstract void setLocalResolver( LocalResolver resolver ) ;
 435 
 436     /** Get the LocalResolver used in this ORB.  This LocalResolver is used for
 437      * register_initial_reference only.
 438      */
 439     public abstract LocalResolver getLocalResolver() ;
 440 
 441     /** Set the operation used in string_to_object calls.  The Operation must expect a
 442      * String and return an org.omg.CORBA.Object.
 443      */
 444     public abstract void setURLOperation( Operation stringToObject ) ;
 445 
 446     /** Get the operation used in string_to_object calls.  The Operation must expect a
 447      * String and return an org.omg.CORBA.Object.
 448      */
 449     public abstract Operation getURLOperation() ;
 450 
 451     /** Set the ServerRequestDispatcher that should be used for handling INS requests.
 452      */
 453     public abstract void setINSDelegate( CorbaServerRequestDispatcher insDelegate ) ;
 454 
 455     // XXX The next 5 operations should be moved to an IORManager.
 456 
 457     /** Factory finders for the various parts of the IOR: tagged components, tagged
 458      * profiles, and tagged profile templates.
 459      */
 460     public abstract TaggedComponentFactoryFinder getTaggedComponentFactoryFinder() ;
 461     public abstract IdentifiableFactoryFinder getTaggedProfileFactoryFinder() ;
 462     public abstract IdentifiableFactoryFinder getTaggedProfileTemplateFactoryFinder() ;
 463 
 464     public abstract ObjectKeyFactory getObjectKeyFactory() ;
 465     public abstract void setObjectKeyFactory( ObjectKeyFactory factory ) ;
 466 
 467     // Logging SPI
 468 
 469     /**
 470      * Returns the logger based on the category.
 471      */
 472     public Logger getLogger( String domain )
 473     {
 474         synchronized (this) {
 475             checkShutdownState();
 476         }
 477         ORBData odata = getORBData() ;
 478 
 479         // Determine the correct ORBId.  There are 3 cases:
 480         // 1. odata is null, which happens if we are getting a logger before
 481         //    ORB initialization is complete.  In this case we cannot determine
 482         //    the ORB ID (it's not known yet), so we set the ORBId to
 483         //    _INITIALIZING_.
 484         // 2. odata is not null, so initialization is complete, but ORBId is set to
 485         //    the default "".  To avoid a ".." in
 486         //    the log domain, we simply use _DEFAULT_ in this case.
 487         // 3. odata is not null, ORBId is not "": just use the ORBId.
 488         String ORBId ;
 489         if (odata == null)
 490             ORBId = "_INITIALIZING_" ;
 491         else {
 492             ORBId = odata.getORBId() ;
 493             if (ORBId.equals(""))
 494                 ORBId = "_DEFAULT_" ;
 495         }
 496 
 497         return getCORBALogger( ORBId, domain ) ;
 498     }
 499 
 500     public static Logger staticGetLogger( String domain )
 501     {
 502         return getCORBALogger( "_CORBA_", domain ) ;
 503     }
 504 
 505     private static Logger getCORBALogger( String ORBId, String domain )
 506     {
 507         String fqLogDomain = CORBALogDomains.TOP_LEVEL_DOMAIN + "." +
 508             ORBId + "." + domain;
 509 
 510         return Logger.getLogger( fqLogDomain, ORBConstants.LOG_RESOURCE_FILE );
 511     }
 512 
 513     /** get the log wrapper class (its type is dependent on the exceptionGroup) for the
 514      * given log domain and exception group in this ORB instance.
 515      */
 516     public LogWrapperBase getLogWrapper( String logDomain,
 517         String exceptionGroup, LogWrapperFactory factory )
 518     {
 519         StringPair key = new StringPair( logDomain, exceptionGroup ) ;
 520 
 521         LogWrapperBase logWrapper = (LogWrapperBase)wrapperMap.get( key );
 522         if (logWrapper == null) {
 523             logWrapper = factory.create( getLogger( logDomain ) );
 524             wrapperMap.put( key, logWrapper );
 525         }
 526 
 527         return logWrapper;
 528     }
 529 
 530     /** get the log wrapper class (its type is dependent on the exceptionGroup) for the
 531      * given log domain and exception group in this ORB instance.
 532      */
 533     public static LogWrapperBase staticGetLogWrapper( String logDomain,
 534         String exceptionGroup, LogWrapperFactory factory )
 535     {
 536         StringPair key = new StringPair( logDomain, exceptionGroup ) ;
 537 
 538         LogWrapperBase logWrapper = (LogWrapperBase)staticWrapperMap.get( key );
 539         if (logWrapper == null) {
 540             logWrapper = factory.create( staticGetLogger( logDomain ) );
 541             staticWrapperMap.put( key, logWrapper );
 542         }
 543 
 544         return logWrapper;
 545     }
 546 
 547     // get a reference to a ByteBufferPool, a pool of NIO ByteBuffers
 548     // NOTE: ByteBuffer pool must be unique per ORB, not per process.
 549     //       There can be more than one ORB per process.
 550     //       This method must also be inherited by both ORB and ORBSingleton.
 551     public ByteBufferPool getByteBufferPool()
 552     {
 553         synchronized (this) {
 554             checkShutdownState();
 555         }
 556         if (byteBufferPool == null)
 557             byteBufferPool = new ByteBufferPoolImpl(this);
 558 
 559         return byteBufferPool;
 560     }
 561 
 562     public abstract void setThreadPoolManager(ThreadPoolManager mgr);
 563 
 564     public abstract ThreadPoolManager getThreadPoolManager();
 565 
 566     public abstract CopierManager getCopierManager() ;
 567 }
 568 
 569 // End of file.