FileDocCategorySizeDatePackage
POARemoteReferenceFactory.javaAPI DocGlassfish v2 API20762Thu May 31 22:04:14 BST 2007com.sun.enterprise.iiop

POARemoteReferenceFactory

public final class POARemoteReferenceFactory extends LocalObject implements RemoteReferenceFactory, ServantLocator
This class implements the RemoteReferenceFactory interface for the RMI/IIOP ORB with POA (Portable Object Adapter). There is one instance of the POARemoteReferenceFactory for each EJB type. It also implements the preinvoke/postinvoke APIs in the POA's ServantLocator interface, which are called before/after every invocation (local or remote). It creates a RMI-IIOP-POA object reference (a stub) for every EJBObject and EJBHome in the EJB container.
author
Kenneth Saks

Fields Summary
static final int
PASS_BY_VALUE_ID
static final int
PASS_BY_REFERENCE_ID
static final int
OTS_POLICY_TYPE
static final int
CSIv2_POLICY_TYPE
static final int
REQUEST_DISPATCH_POLICY_TYPE
static final int
SFSB_VERSION_POLICY_TYPE
private static final Logger
logger
private static final int
GET_TIE_EXCEPTION_CODE
private Container
container
private EjbDescriptor
ejbDescriptor
private ORB
orb
private POAProtocolMgr
protocolMgr
private com.sun.corba.ee.spi.presentation.rmi.PresentationManager
presentationMgr
private com.sun.corba.ee.spi.oa.rfm.ReferenceFactory
ejbHomeReferenceFactory
private PresentationManager.StubFactory
ejbHomeStubFactory
private String
ejbHomeRepositoryId
private com.sun.corba.ee.spi.oa.rfm.ReferenceFactory
ejbObjectReferenceFactory
private PresentationManager.StubFactory
ejbObjectStubFactory
private String
ejbObjectRepositoryId
private String
remoteBusinessIntf
private boolean
isRemoteHomeView
private String
poaId_EJBHome
private String
poaId_EJBObject
static final int
EJBID_OFFSET
private static final int
INSTANCEKEYLEN_OFFSET
private static final int
INSTANCEKEY_OFFSET
Constructors Summary
POARemoteReferenceFactory(Container container, POAProtocolMgr protocolMgr, ORB orb, boolean remoteHomeView, String id)

 


        
			            
    
	this.protocolMgr = protocolMgr;
	this.orb = orb;
        this.poaId_EJBHome   = id + "-EJBHome";
        this.poaId_EJBObject = id + "-EJBObject";
        this.presentationMgr = 
            ((com.sun.corba.ee.spi.orb.ORB) orb).getPresentationManager();
	this.container = container;
	this.ejbDescriptor = container.getEjbDescriptor();
        this.isRemoteHomeView = remoteHomeView;

	ClassLoader loader = container.getClassLoader();

	// NOTE: ReferenceFactory creation happens in setRepositoryIds.
	
	if (logger.isLoggable(Level.FINE)) {
	    logger.log(Level.FINE, 
		       "POARemoteReferenceFactory:"
		       + " " + poaId_EJBHome
		       + " " + poaId_EJBObject
		       + " " + ejbDescriptor);
	}
    
Methods Summary
private org.omg.CORBA.Object_createRef(com.sun.corba.ee.spi.oa.rfm.ReferenceFactory rf, byte[] instanceKey, java.lang.String repoid)


        if ( logger.isLoggable(Level.FINE) ) {
	    logger.info("\t\tIn POARemoteReferenceFactory._createRef, " +
                        "repositoryId = " + repoid);
        }

         // Create the ejbKey using EJB's unique id + instanceKey
        byte[] ejbKey = createEJBKey(ejbDescriptor.getUniqueId(), 
                                     instanceKey);
        
	org.omg.CORBA.Object obj = rf.createReference( ejbKey ) ;

        return obj;
    
public voidcleanupClass(java.lang.Class clazz)


        try {
            presentationMgr.flushClass(clazz);
        } catch(Exception e) {
            logger.log(Level.FINE, "cleanupClass error", e);
        }
    
private byte[]createEJBKey(long ejbId, byte[] instanceKey)

	byte[] ejbkey = new byte[INSTANCEKEY_OFFSET+instanceKey.length];

	Utility.longToBytes(ejbId, ejbkey, EJBID_OFFSET);
	Utility.intToBytes(instanceKey.length, ejbkey, INSTANCEKEYLEN_OFFSET);
	System.arraycopy(instanceKey, 0, ejbkey, INSTANCEKEY_OFFSET, 
							    instanceKey.length);
	return ejbkey;
    
public javax.ejb.EJBHomecreateHomeReference(byte[] homeKey)

	return (EJBHome)createRef(homeKey, ejbHomeReferenceFactory,
	    ejbHomeStubFactory, ejbHomeRepositoryId ) ;
    
private java.rmi.RemotecreateRef(byte[] instanceKey, com.sun.corba.ee.spi.oa.rfm.ReferenceFactory rf, PresentationManager.StubFactory stubFactory, java.lang.String repoid)

	try {
  	    PresentationManager.StubFactory stubFact = stubFactory;
	    org.omg.CORBA.Object ref = _createRef(rf, instanceKey,repoid);

	    org.omg.CORBA.Object stub = stubFact.makeStub();
            Delegate delegate = StubAdapter.getDelegate(ref);
            StubAdapter.setDelegate(stub, delegate);               

	    return (Remote) stub;

	} catch(Exception e) {
            logger.log(Level.SEVERE, "iiop.createreference_exception",
                       e.toString());

	    throw new RuntimeException("Unable to create reference ",e);
	}
    
private com.sun.corba.ee.spi.oa.rfm.ReferenceFactorycreateReferenceFactory(java.lang.String poaId, java.lang.String repoid)

      try {
	if (logger.isLoggable(Level.FINE)) {
	    logger.log(Level.WARNING, 
		       ".createReferenceFactory->: " + poaId + " " + repoid);
	}

	ReferenceFactoryManager rfm = 
	    (ReferenceFactoryManager)orb.resolve_initial_references(
		ORBConstants.REFERENCE_FACTORY_MANAGER ) ;

	List<Policy> policies = new ArrayList<Policy>();

	// Servant caching for local RMI-IIOP invocation performance
        policies.add(ServantCachingPolicy.getPolicy());

	// OTS Policy
	policies.add(new OTSPolicy());

	if (logger.isLoggable(Level.FINE)) {
	    logger.log(Level.WARNING, 
		       ".createReferenceFactory: " + poaId + " " + repoid
		       + ": " + ejbDescriptor);
	}

	// CSIv2 Policy
	policies.add(new CSIv2Policy(ejbDescriptor));

	IASEjbExtraDescriptors extraDesc
	    = ejbDescriptor.getIASEjbExtraDescriptors();
	String threadPoolName = extraDesc.getUseThreadPoolId();
	int threadPoolNumericID = 0;
	boolean usePassByReference = extraDesc.getPassByReference();

	if (usePassByReference) {
	    policies.add(new CopyObjectPolicy(PASS_BY_REFERENCE_ID));
	}

	if (threadPoolName != null) {
	    ThreadPoolManager threadPoolManager
		= S1ASThreadPoolManager.getThreadPoolManager();
	    try {
		threadPoolNumericID = threadPoolManager.getThreadPoolNumericId(
		    threadPoolName);
		policies.add(new RequestPartitioningPolicy(threadPoolNumericID));
	    } catch (Exception ex) {
                logger.log(Level.WARNING, "Not using threadpool-request-partitioning...", ex);
	    }
	}

    logger.log(Level.INFO, "POARemoteRefFactory checking if SFSBVersionPolicy need to be added");
    EJBServerConfigLookup ejbConfigLookup =
        new EJBServerConfigLookup(ejbDescriptor);
    boolean addSFSBVersionPolicy = EJBServerConfigLookup.needToAddSFSBVersionInterceptors();
    logger.log(Level.INFO, "POARemoteRefFactory addSFSBVersionPolicy? " + addSFSBVersionPolicy);
    if (addSFSBVersionPolicy) {
        if (container instanceof StatefulSessionContainer) {
            StatefulSessionContainer sfsbCon = (StatefulSessionContainer) container;
            if (sfsbCon.isHAEnabled()) {
                policies.add(new SFSBVersionPolicy(ejbDescriptor.getUniqueId()));
            }
        }
    }


	if (logger.isLoggable(Level.FINE)) {
	    String jndiName = ejbDescriptor.getJndiName();
	    logger.log(Level.FINE, "Using Thread-Pool: ["
		+ threadPoolName + " ==> " + threadPoolNumericID
		+ "] for jndi name: " + jndiName);
	    logger.log(Level.FINE, "Pass by reference: ["
		+ usePassByReference
		+ "] for jndi name: " + usePassByReference);
	}

	// DisableClearTextIIOP policy which sets IIOP Profile port to 0 
	// if EJB allows only SSL invocations
	CSIV2TaggedComponentInfo ctc = new CSIV2TaggedComponentInfo(orb);
	Set iorDescSet = ejbDescriptor.getIORConfigurationDescriptors();
        if ( ctc.allMechanismsRequireSSL(iorDescSet) ) {
	    if (logger.isLoggable(Level.FINE)) {
		logger.log(Level.WARNING, 
			   ".createReferenceFactory: " + poaId + " " + repoid
			   + ": adding ZeroPortPolicy");
	    }
	    policies.add(ZeroPortPolicy.getPolicy());
        }

	if (logger.isLoggable(Level.FINE)) {
	    logger.log(Level.WARNING, 
		       ".createReferenceFactory: " + poaId + " " + repoid
		       + ": policies: " + policies);
	}
	ReferenceFactory rf = rfm.create( poaId, repoid, policies, this ) ;
	return rf ;

      } finally {
	if (logger.isLoggable(Level.FINE)) {
	    logger.log(Level.WARNING, 
		       ".createReferenceFactory<-: " + poaId + " " + repoid);
	}
      }
    
public java.rmi.RemotecreateRemoteReference(byte[] instanceKey)

	return createRef(instanceKey, ejbObjectReferenceFactory,
	    ejbObjectStubFactory, ejbObjectRepositoryId );
    
public voiddestroy()

        try {

	    ejbHomeReferenceFactory.destroy() ;
	    ejbObjectReferenceFactory.destroy() ;
	    ejbHomeReferenceFactory = null ;
	    ejbObjectReferenceFactory = null ;

            container = null;
            ejbDescriptor = null;

            orb = null;
            protocolMgr = null;

        } catch (Throwable th) {
            logger.log(Level.SEVERE, "Exception during "
                       + "POARemoteRefFactory::destroy()", th);
        }
    
public voiddestroyReference(java.rmi.Remote remoteRef, java.rmi.Remote remoteObj)
Disconnect an EJBObject or EJBHome from the ORB.

	// Note: the POAs have the NON_RETAIN policy so they dont maintain
	// any state for objects. We only need to unexport the object from
	// the RMI/IIOP machinery.
	// The following call also does tie.deactivate() for the remoteObj's tie
	try {
	    Util.unexportObject(remoteObj);
	} catch ( RuntimeException ex ) {
	    // A bug in Util.unexportObject causes this exception 
	    // Ignore it.
	} catch ( java.lang.Exception nsoe ){
	    // eat it and ignore it.
	}
    
private java.lang.StringgetRepositoryId(java.lang.Class c)


        // Using PresentationManager to get repository ID will always work,
        // independent of whether we have generated static RMI-IIOP stubs.

        PresentationManager.ClassData cData = presentationMgr.getClassData(c);
        String[] typeIds = cData.getTypeIds();  

	if (logger.isLoggable(Level.FINE)) {
	    logger.log(Level.FINE, ".getRepositoryId: " + typeIds[0]);
	}

        // Repository id is always 1st element in array.
        return typeIds[0];
    
public booleanhasSameContainerID(org.omg.CORBA.Object obj)

	boolean result = false;
	try {
	    IOR ior = ((com.sun.corba.ee.spi.orb.ORB)orb).getIOR(obj, false);
	    java.util.Iterator iter = ior.iterator();

	    byte[] oid = null;
	    if (iter.hasNext()) {
		TaggedProfile profile = (TaggedProfile) iter.next();
		ObjectKey objKey = profile.getObjectKey();
		oid = objKey.getId().getId();
	    }

	    if ((oid != null) && (oid.length > INSTANCEKEY_OFFSET)) {
		long cid = Utility.bytesToLong(oid, EJBID_OFFSET);
		//To be really sure that is indeed a ref generated
		//  by our container we do the following checks
		int keyLen = Utility.bytesToInt(oid, INSTANCEKEYLEN_OFFSET);
		if (oid.length == keyLen + INSTANCEKEY_OFFSET) {
		    result = (cid == ejbDescriptor.getUniqueId());
		}
		if (logger.isLoggable(Level.FINE)) {
		    StringBuffer sbuf = new StringBuffer();
		    sbuf.append("hasSameContainerID() result: ").append(result)
			.append("; because ==> oid.length: ").append(oid.length)
			.append("; instance-key-length: ").append(keyLen)
			.append("; expected oid.length: ")
			.append(keyLen).append("+").append(INSTANCEKEY_OFFSET)
			.append("; myContainrID: ")
			.append(ejbDescriptor.getUniqueId())
			.append("; obj.containerID: ")
			.append(cid);
		    logger.log(Level.FINE, sbuf.toString());
		}
	    } else {
		if (logger.isLoggable(Level.FINE)) {
		    if (oid == null) {
			logger.log(Level.FINE, "hasSameContainerID() failed because oid=null");
		    } else {
			logger.log(Level.FINE, "hasSameContainerID() failed because "
				+ "oid.length= " + oid.length
				+ "; but INSTANCE_KEY_OFFSET= " + INSTANCEKEY_OFFSET);
		    }
		}
	    }
	} catch (Exception ex) {
	    logger.log(Level.FINE, "Exception while checking for same containerID", ex);
	    throw ex;
	}
	return result;
    
public voidpostinvoke(byte[] ejbKey, org.omg.PortableServer.POA adapter, java.lang.String operation, java.lang.Object cookie, org.omg.PortableServer.Servant servant)

	Remote target = null;
	if ( servant != null ) {
	    target = ((Tie)servant).getTarget();
        }
        // Always release, since that restores the previous context class
        // loader. 
	container.releaseTargetObject(target);
    
public org.omg.PortableServer.Servantpreinvoke(byte[] ejbKey, org.omg.PortableServer.POA adapter, java.lang.String operation, org.omg.PortableServer.ServantLocatorPackage.CookieHolder cookieHolder)
This is the implementation of ServantLocator.preinvoke() It is called from the POA before every remote invocation. Return a POA Servant (which is the RMI/IIOP Tie for EJBObject/EJBHome).

	if (logger.isLoggable(Level.FINE)) {
	    logger.log(Level.FINE,"In preinvoke for operation:" + operation);
	}

	// get instance key
	int keyLen = Utility.bytesToInt(ejbKey, INSTANCEKEYLEN_OFFSET);
	byte[] instanceKey = new byte[keyLen];
	System.arraycopy(ejbKey, INSTANCEKEY_OFFSET, instanceKey, 0, keyLen);

        Servant servant = null;
        try {
            while ( servant == null ) {
		// get the EJBObject / EJBHome
	        Remote targetObj = 
                    container.getTargetObject(instanceKey, 
                                              (isRemoteHomeView ? null :
                                               remoteBusinessIntf));

                // This could be null in rare cases for sfsbs and entity 
                // beans.  It would be preferable to push the retry logic
                // within the sfsb container and entity container 
                // implementations of getTargetObject, but for now let's keep
                // the looping logic the same as it has always been.
                if( targetObj != null ) {
                    // get the Tie which is the POA Servant
		    //fix for bug 6484935
		    Tie tie = (Tie)java.security.AccessController.doPrivileged(
						new java.security.PrivilegedAction() {
                        public Tie run()  {
			    return presentationMgr.getTie();
			}
		    });
                    tie.setTarget(targetObj);
                    servant = (Servant) tie;
                }
            }
        } catch (NoSuchObjectLocalException e) {
            logger.log(Level.SEVERE,"iiop.gettie_exception", e);
            throw new OBJECT_NOT_EXIST( GET_TIE_EXCEPTION_CODE,
					CompletionStatus.COMPLETED_NO);
        } catch (RuntimeException e) {
            logger.log(Level.SEVERE,"iiop.runtime_exception", e);
	    throw e;
	}
        return servant;
    
public voidsetRepositoryIds(java.lang.Class homeIntf, java.lang.Class remoteIntf)


        ClassLoader appClassLoader = container.getClassLoader();

        PresentationManager.StubFactoryFactory sff = 
            ((com.sun.corba.ee.spi.orb.ORB) orb).getStubFactoryFactory();

        // Home
        ejbHomeStubFactory = 
            sff.createStubFactory( homeIntf.getName(), false,
                                   "", null, appClassLoader);
        String[] ejbHomeTypeIds = ejbHomeStubFactory.getTypeIds();
        ejbHomeRepositoryId = ejbHomeTypeIds[0];

        ejbObjectStubFactory = 
	    sff.createStubFactory( remoteIntf.getName(), false,
				   "", null, appClassLoader);
        String[] ejbObjectTypeIds = ejbObjectStubFactory.getTypeIds();
        ejbObjectRepositoryId = ejbObjectTypeIds[0];

	if (logger.isLoggable(Level.FINE)) {
	    logger.log(Level.FINE, 
		       ".setRepositoryIds:"
		       + " " + ejbHomeRepositoryId
		       + " " + ejbObjectRepositoryId);
	}

	try {
	
	    ejbHomeReferenceFactory 
		= createReferenceFactory(poaId_EJBHome, ejbHomeRepositoryId);
	    ejbObjectReferenceFactory 
		= createReferenceFactory(poaId_EJBObject, ejbObjectRepositoryId);
	} catch (Exception e) {
	    throw new RuntimeException(e);
	}

        if( !isRemoteHomeView ) {
            remoteBusinessIntf = remoteIntf.getName();
        }