alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Glassfish example source code file (POARemoteReferenceFactory.java)

This example Glassfish source code file (POARemoteReferenceFactory.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Glassfish tags/keywords

corba, ejb, exception, exception, instancekey_offset, instancekeylen_offset, object, object, override, override, referencefactory, remote, rmi, runtimeexception, security, servant, servlet, string, string, util

The Glassfish POARemoteReferenceFactory.java source code

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

package org.glassfish.enterprise.iiop.impl;


import javax.ejb.NoSuchObjectLocalException;

import java.rmi.Remote;

import java.security.AccessController ;
import java.security.PrivilegedAction ;

import org.omg.CORBA.portable.Delegate;

import org.glassfish.enterprise.iiop.api.RemoteReferenceFactory;

import org.glassfish.enterprise.iiop.spi.EjbContainerFacade;

import org.omg.PortableServer.POA ;
import org.omg.PortableServer.Servant ;
import org.omg.PortableServer.ServantLocator ;
import org.omg.PortableServer.ServantLocatorPackage.CookieHolder ;

import com.sun.logging.LogDomains;

import com.sun.enterprise.deployment.EjbDescriptor;

import com.sun.enterprise.deployment.runtime.IASEjbExtraDescriptors;

// TODO Only needed for checkpointing
// import com.sun.ejb.base.sfsb.util.EJBServerConfigLookup;

import com.sun.corba.ee.spi.extension.ServantCachingPolicy;
import com.sun.corba.ee.spi.extension.ZeroPortPolicy;
import com.sun.corba.ee.spi.extension.CopyObjectPolicy;

import com.sun.corba.ee.spi.presentation.rmi.PresentationManager ;

import com.sun.corba.ee.spi.presentation.rmi.StubAdapter;
import com.sun.corba.ee.spi.oa.rfm.ReferenceFactory ;
import com.sun.corba.ee.spi.oa.rfm.ReferenceFactoryManager ;

import com.sun.corba.ee.spi.orbutil.ORBConstants;
import com.sun.corba.ee.org.omg.CORBA.SUNVMCID;
import com.sun.corba.ee.spi.ior.IOR;
import com.sun.corba.ee.spi.ior.ObjectKey;
import com.sun.corba.ee.spi.ior.TaggedProfile;
import com.sun.corba.ee.spi.orb.ORB;

import com.sun.enterprise.util.Utility;

import com.sun.corba.ee.spi.orbutil.codegen.Wrapper ;
import java.util.List;
import java.util.ArrayList;
import java.util.logging.Level;
import javax.rmi.CORBA.Tie;
import javax.rmi.CORBA.Util;
import org.omg.CORBA.CompletionStatus;
import org.omg.CORBA.OBJECT_NOT_EXIST;
import org.omg.CORBA.Policy;

/**
 * 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
 */

public final class POARemoteReferenceFactory extends org.omg.CORBA.LocalObject 
			implements RemoteReferenceFactory, ServantLocator
{
    static final int PASS_BY_VALUE_ID = 0;
    static final int PASS_BY_REFERENCE_ID = 1;

    static final int OTS_POLICY_TYPE = SUNVMCID.value + 123; 
    static final int CSIv2_POLICY_TYPE = SUNVMCID.value + 124; 
    static final int REQUEST_DISPATCH_POLICY_TYPE = SUNVMCID.value + 125; 
    static final int SFSB_VERSION_POLICY_TYPE = SUNVMCID.value + 126; 
    
    private static final java.util.logging.Logger logger =
		java.util.logging.Logger.getLogger(LogDomains.CORBA_LOGGER);
    private static final int GET_TIE_EXCEPTION_CODE = 9999;

    private EjbContainerFacade container;
    private EjbDescriptor ejbDescriptor;
    private ClassLoader appClassLoader;

    private ORB orb;
    private POAProtocolMgr protocolMgr;
    private PresentationManager presentationMgr;

    private ReferenceFactory ejbHomeReferenceFactory ;
    private PresentationManager.StubFactory ejbHomeStubFactory;
    private String ejbHomeRepositoryId;

    private ReferenceFactory ejbObjectReferenceFactory ;
    private PresentationManager.StubFactory ejbObjectStubFactory;
    private String ejbObjectRepositoryId;

    private String remoteBusinessIntf;
    
    // true if remote home view.  false if remote business view.
    // Used when getting target object for an invocation.
    private boolean isRemoteHomeView;

    private String poaId_EJBHome;
    private String poaId_EJBObject;

    // The EJB key format with field-name(size in bytes): 
    // -----------------------------------------
    // | EJB ID(8) | INSTANCEKEY | INSTANCEKEY | 
    // |           | LENGTH(4)   |   (unknown) |
    // -----------------------------------------
    // The following are the offsets for the fields in the EJB key.
    static final int EJBID_OFFSET = 0;
    private static final int INSTANCEKEYLEN_OFFSET = 8;
    private static final int INSTANCEKEY_OFFSET = 12;

    POARemoteReferenceFactory(EjbContainerFacade 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 = orb.getPresentationManager();
        this.container = container;
        this.ejbDescriptor = container.getEjbDescriptor();
        this.isRemoteHomeView = remoteHomeView;

        appClassLoader = container.getClassLoader();

        // NOTE: ReferenceFactory creation happens in setRepositoryIds.
    }

    @Override
    public int getCSIv2PolicyType() {
        return CSIv2_POLICY_TYPE;
    }

    private String getRepositoryId(Class c) throws Exception {

        // 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: {0}", typeIds[0]);
	    }

        // Repository id is always 1st element in array.
        return typeIds[0];
    }

    @Override
    public void setRepositoryIds(Class homeIntf, Class remoteIntf)
    {
        PresentationManager.StubFactoryFactory sff = 
            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:" + " " + "{0} {1}",
                new Object[]{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();
        }
            
    }

    @Override
    public void cleanupClass(Class clazz) {

        try {
            presentationMgr.flushClass(clazz);
        } catch(Exception e) {
            logger.log(Level.FINE, "cleanupClass error", e);
        }
    }

    private ReferenceFactory createReferenceFactory(String poaId, String repoid ) throws Exception {
        try {
            if (logger.isLoggable(Level.FINE)) {
                logger.log(Level.FINE, ".createReferenceFactory->: {0} {1}",
                    new Object[]{poaId, repoid});
	    }

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

	    List<Policy> policies = new ArrayList();

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

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

	    if (logger.isLoggable(Level.FINE)) {
	        logger.log(Level.FINE, ".createReferenceFactory: {0} {1}: {2}",
                    new Object[]{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));
	    }

            /** TODO get thread pool name from config
	    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);
	        }
	    }
            **/

            /** TODO
            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: [{0} ==> {1}] for jndi name: {2}",
                    new Object[]{threadPoolName, threadPoolNumericID, jndiName});
                logger.log(Level.FINE, "Pass by reference: [{0}] for jndi name: {1}",
                    new Object[]{usePassByReference, usePassByReference});
            }

	    // DisableClearTextIIOP policy which sets IIOP Profile port to 0
	    // if EJB allows only SSL invocations
	    if ( ejbDescriptor.allMechanismsRequireSSL() ) {
	        if (logger.isLoggable(Level.FINE)) {
                    logger.log(Level.WARNING,
                        ".createReferenceFactory: {0} {1}: adding ZeroPortPolicy",
                        new Object[]{poaId, repoid});
	        }
	        policies.add(ZeroPortPolicy.getPolicy());
	    }


	    if (logger.isLoggable(Level.FINE)) {
	        logger.log(Level.FINE, 
                    ".createReferenceFactory: {0} {1}: policies: {2}",
                    new Object[]{poaId, repoid, policies});
	    }

	    ReferenceFactory rf = rfm.create( poaId, repoid, policies, this ) ;
	    return rf ;
        } finally {
	    if (logger.isLoggable(Level.FINE)) {
	        logger.log(Level.WARNING, 
                    ".createReferenceFactory<-: {0} {1}",
                    new Object[]{poaId, repoid});
	    }
        }
    }


    @Override
    public java.rmi.Remote createRemoteReference(byte[] instanceKey)
    {
	    return createRef(instanceKey, ejbObjectReferenceFactory,
	        ejbObjectStubFactory, ejbObjectRepositoryId );
    }


    @Override
    public Remote createHomeReference(byte[] homeKey)
    {
	    return createRef(homeKey, ejbHomeReferenceFactory,
	        ejbHomeStubFactory, ejbHomeRepositoryId ) ;
    }

    private void setClassLoader() {
        ClassLoader cl ;
        SecurityManager sman = System.getSecurityManager() ;
        if (sman == null) {
            cl = this.getClass().getClassLoader() ;
        } else {
            cl = AccessController.doPrivileged( 
                new PrivilegedAction<ClassLoader>() {
                    @Override
                    public ClassLoader run() {
                        return this.getClass().getClassLoader() ;
                    }
                }
            ) ;
        }

        Wrapper._setClassLoader( cl ) ;
    }

    private Remote createRef(byte[] instanceKey, ReferenceFactory rf, 
        PresentationManager.StubFactory stubFactory, String repoid )
    {
        try {
            PresentationManager.StubFactory stubFact = stubFactory;
            org.omg.CORBA.Object ref = _createRef(rf, instanceKey,repoid);
                
            // Set the ClassLoader to the ClassLoader for this class,
            // which is loaded by the OSGi bundle ClassLoader for the
            // orb-iiop bundle, which depends on (among others) the
            // glassfish-corba-codegen bundle, which contains the
            // CodegenProxyStub class needed inside the makeStub call.
            setClassLoader() ;

            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);
        }
    }

    // NOTE: The repoid is only needed for logging.
    private org.omg.CORBA.Object _createRef( ReferenceFactory rf, 
	    byte[] instanceKey, String repoid ) throws Exception {

        if ( logger.isLoggable(Level.FINE) ) {
            logger.log(Level.FINE,
                "\t\tIn POARemoteReferenceFactory._createRef, repositoryId = {0}",
                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;
    }
   
    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;
    }

    /**
     * Disconnect an EJBObject or EJBHome from the ORB.
     */
    @Override
    public void destroyReference(Remote remoteRef, Remote remoteObj)
    {
        // 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.
        }
    }

    /**
     * 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).
     * @param ejbKey 
     * @param cookieHolder
     */
    @Override
    public Servant preinvoke(byte[] ejbKey, POA adapter, String operation,
                                CookieHolder cookieHolder)
                throws org.omg.PortableServer.ForwardRequest
    {
        if (logger.isLoggable(Level.FINE)) {
            logger.log(Level.FINE, "In preinvoke for operation:{0}", 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
                    @SuppressWarnings("unchecked")
                    Tie tie = (Tie)AccessController.doPrivileged( 
                        new PrivilegedAction() {
                        @Override
                            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;
    }

    @Override
    public void postinvoke(byte[] ejbKey, POA adapter, String operation,
                            java.lang.Object cookie, Servant servant)
    {
        Remote target = null;
        if ( servant != null ) {
            target = ((Tie)servant).getTarget();
        }

        // Always release, since that restores previous context class loader.
        container.releaseTargetObject(target);
    }


    @Override
    public void destroy() {
        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);
        }
    }

    @Override
    public boolean hasSameContainerID(org.omg.CORBA.Object obj)
	throws Exception
    {
	boolean result = false;
	try {
	    IOR ior = (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)) {
                    StringBuilder sbuf = new StringBuilder();
                    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= "
                            + "{0}; but INSTANCE_KEY_OFFSET= {1}",
                            new Object[]{oid.length, INSTANCEKEY_OFFSET});
                    }
                }
	    }
	} catch (Exception ex) {
	    logger.log(Level.FINE, "Exception while checking for same containerID", ex);
	    throw ex;
	}

	return result;
    }
}

Other Glassfish examples (source code examples)

Here is a short list of links related to this Glassfish POARemoteReferenceFactory.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.