All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.ejb.EjbNamingReferenceManagerImpl Maven / Gradle / Ivy

There is a newer version: 7.2024.1.Alpha1
Show newest version
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 1997-2012 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.
 */
// Portions Copyright [2018-2021] [Payara Foundation and/or its affiliates]

package com.sun.ejb;

import com.sun.ejb.containers.EJBContextImpl;
import com.sun.ejb.containers.EJBTimerService;
import com.sun.enterprise.container.common.spi.EjbNamingReferenceManager;
import com.sun.enterprise.deployment.EjbReferenceDescriptor;
import org.glassfish.api.invocation.ComponentInvocation;
import org.glassfish.api.invocation.InvocationManager;
import org.glassfish.enterprise.iiop.api.GlassFishORBHelper;
import jakarta.inject.Inject;
import org.jvnet.hk2.annotations.Service;
import jakarta.inject.Provider;
import javax.naming.Context;
import com.sun.enterprise.util.Utility;
import org.omg.CORBA.ORB;
import javax.naming.NamingException;

/**
 * @author Mahesh Kannan
 */

@Service
public class EjbNamingReferenceManagerImpl
    implements EjbNamingReferenceManager {

    private static final String CORBANAME = "corbaname:";

    @Inject
    InvocationManager invMgr;

    @Inject
    Provider glassFishORBHelperProvider;

    @Override
    public Object resolveEjbReference(EjbReferenceDescriptor ejbRefDesc, Context context)
        throws NamingException {

        Object jndiObj = null;
        boolean resolved = false;


        if( ejbRefDesc.isLocal() ) {
            // local ejb dependencies if there's a lookup string, use that.
            // Otherwise, the ejb will be resolved by EJBUtils.
            if( ejbRefDesc.hasLookupName()) {
                jndiObj = context.lookup(ejbRefDesc.getLookupName());
                resolved = true;
            }
        } else if (!ejbRefDesc.hasJndiName() && ejbRefDesc.hasLookupName()) {
            // For a remote reference, only do a context lookup if there is no
            // jndi name. 
            // The thread context class loader usually is the EAR class loader,
            // which is able to load business interfaces.  But if the lookup request
            // originated from appclient, and the ejb-ref is under java:app/env,
            // and it also has a lookup-name, then we need to set the EAR class
            // loader to the thread.  Issue 17376.
            try {
                jndiObj = context.lookup(ejbRefDesc.getLookupName());
            } catch (NamingException e) {
                ClassLoader oldLoader = null;
                try {
                    oldLoader = Utility.setContextClassLoader(
                            ejbRefDesc.getReferringBundleDescriptor().getClassLoader());
                    jndiObj = context.lookup(ejbRefDesc.getLookupName());
                } finally {
                    Utility.setContextClassLoader(oldLoader);
                }
            }
            resolved = true;
        } else if( ejbRefDesc.hasJndiName() &&     
                   ejbRefDesc.getJndiName().startsWith("java:app/") &&
                   !ejbRefDesc.getJndiName().startsWith("java:app/env/")) {

            // This could be an @EJB dependency in an appclient whose target name
            // is a portable java:app ejb name.  Try the global version.  If that
            // doesn't work, the javaURLContext logic should be able to figure it
            // out.
            String remoteJndiName = ejbRefDesc.getJndiName();

            String appName = (String) context.lookup("java:app/AppName");
            String newPrefix = "java:global/" + appName + "/";

            int javaAppLength = "java:app/".length();
            String globalLookup = newPrefix + remoteJndiName.substring(javaAppLength);

            jndiObj = context.lookup(globalLookup);
            resolved = true;

        } else {

            // Get actual jndi-name from ejb module.
            String remoteJndiName = EJBUtils.getRemoteEjbJndiName(ejbRefDesc);

            // We could be resolving an ejb-ref as part of a remote lookup thread.  In that
            // case the context class loader won't be set appropriately on the thread
            // being used to process the remote naming request.   We can't just always
            // set the context class loader to the class loader of the application module
            // that defined the ejb reference.  That would cause ClassCastExceptions
            // when the returned object is assigned within a cross-application intra-server
            // lookup. So, just try to lookup the interface associated with the ejb-ref
            // using the context class loader.  If that doesn't work, explicitly use the
            // defining application's class loader.

            ClassLoader origClassLoader = Utility.getClassLoader();
            boolean setCL = false;

            try {

                try {
                    
                    String refInterface = ejbRefDesc.isEJB30ClientView() ?
                       ejbRefDesc.getEjbInterface() : ejbRefDesc.getHomeClassName();
                    origClassLoader.loadClass(refInterface);

                } catch(ClassNotFoundException e) {

                     ClassLoader referringBundleClassLoader =
                             ejbRefDesc.getReferringBundleDescriptor().getClassLoader();
                     Utility.setContextClassLoader(referringBundleClassLoader);
                     setCL = true;

                }

                /* For remote ejb refs, first lookup the target remote object
                 * and pass it to the next stage of ejb ref resolution.
                 * If the string is a "corbaname:...." URL
                 * the lookup happens thru the corbanameURL context,
                 * else it happens thru the context provided by the NamingManager.
                 *
                 * NOTE : we might need some additional logic to handle cross-server
                 * MEJB resolution for cluster support post V3 FCS.
                 */
                if (remoteJndiName.startsWith(CORBANAME)) {
                    GlassFishORBHelper orbHelper = glassFishORBHelperProvider.get();

                    ORB orb = orbHelper.getORB();
                    jndiObj = (Object) orb.string_to_object(remoteJndiName);
                } else {
                    jndiObj = context.lookup(remoteJndiName);
                }
                
            } catch(Exception e) {
                // Important to make the real underlying lookup name part of the exception.
                NamingException ne = new NamingException("Exception resolving Ejb for '" +
                    ejbRefDesc + "' .  Actual (possibly internal) Remote JNDI name used for lookup is '" +
                    remoteJndiName + "'");
                ne.initCause(e);
                throw ne;
            } finally {
                if( setCL ) {
                    Utility.setContextClassLoader(origClassLoader);
                }
            }
        }

        return resolved ? jndiObj : EJBUtils.resolveEjbRefObject(ejbRefDesc, jndiObj);
    }

    @Override
    public boolean isEjbReferenceCacheable(EjbReferenceDescriptor ejbRefDesc) {
        // Ejb-ref is only eligible for caching if it refers to the legacy
        // Home view and it is resolved to an ejb within the same application.
        return ( (!ejbRefDesc.isEJB30ClientView()) &&
                 (ejbRefDesc.getEjbDescriptor() != null) );

        // caching not enabled.
        //return false;
    }


    @Override
    public Object getEJBContextObject(String contextType) {

        ComponentInvocation currentInv = invMgr.getCurrentInvocation();

        if(currentInv == null) {
            throw new IllegalStateException("no current invocation");
        } else if (currentInv.getInvocationType() !=
                   ComponentInvocation.ComponentInvocationType.EJB_INVOCATION) {
            throw new IllegalStateException
                ("Illegal invocation type for EJB Context : "
                 + currentInv.getInvocationType());
        }

        EjbInvocation ejbInv = (EjbInvocation) currentInv;

        Object returnObject = ejbInv.context;

        if (contextType.equals("jakarta.ejb.TimerService")) {
            returnObject = EJBTimerService.getEJBTimerServiceWrapper((EJBContextImpl) ejbInv.context);
        }

        return returnObject;
    }


}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy