FileDocCategorySizeDatePackage
EJBUtils.javaAPI DocGlassfish v2 API29131Mon Jun 11 14:56:34 BST 2007com.sun.ejb

EJBUtils

public class EJBUtils extends Object
A handy class with static utility methods.

Fields Summary
private static final Logger
_logger
private static final String
EJB_USE_STATIC_CODEGEN_PROP
private static final String
REMOTE30_HOME_JNDI_SUFFIX
private static Boolean
ejbUseStaticCodegen_
private static final String
CORBA_INS_PREFIX
Constructors Summary
Methods Summary
public static com.sun.ejb.containers.RemoteBusinessWrapperBasecreateRemoteBusinessObject(java.lang.String businessInterface, java.rmi.Remote delegate)


        ClassLoader appClassLoader = 
            getBusinessIntfClassLoader(businessInterface);
        
        return createRemoteBusinessObject(appClassLoader,
                                          businessInterface, delegate);
    
public static com.sun.ejb.containers.RemoteBusinessWrapperBasecreateRemoteBusinessObject(java.lang.ClassLoader loader, java.lang.String businessInterface, java.rmi.Remote delegate)


        String wrapperClassName = EJBUtils.getGeneratedRemoteWrapperName
            (businessInterface);

        Class clientWrapperClass = loader.loadClass(wrapperClassName);
        
        Constructor ctors[] = clientWrapperClass.getConstructors();
        
        Constructor ctor = null;
        for(Constructor next : ctors) {
            if (next.getParameterTypes().length > 0 ) {
                ctor = next;
                break;
            }
        }
        
        Object obj = ctor.newInstance(new Object[] 
            { delegate, businessInterface } );

        return (RemoteBusinessWrapperBase) obj;
    
public static final java.lang.ObjectdeserializeObject(byte[] data, java.lang.ClassLoader loader, boolean resolveObject)
Utility method for deserializing EJBs, primary keys and container-managed fields, all of which may include Remote EJB references, Local refs, JNDI Contexts etc which are not Serializable.

        return IOUtils.deserializeObject(data, resolveObject, loader);
    
public static final java.lang.ObjectdeserializeObject(byte[] data, java.lang.ClassLoader loader)

        return IOUtils.deserializeObject(data, true, loader);
    
public static voiddeserializeObjectFields(java.lang.Class clazz, java.lang.Object instance, java.io.ObjectInputStream ois)


        final ObjectInputStream objInputStream = ois;

        // Use helper method to get sorted list of fields eligible
        // for deserialization.  This ensures that we correctly match
        // serialized state with its corresponding field.
        for(Field next : getSerializationFields(clazz)) {

            try {

                final Field nextField = next;
                final Object value = ois.readObject();
                final Object theInstance = instance;
                
                if(System.getSecurityManager() == null) {
                    if( !nextField.isAccessible() ) {
                        nextField.setAccessible(true);
                    }
                    nextField.set(theInstance, value);
                } else {
                    java.security.AccessController.doPrivileged(
                            new java.security.PrivilegedExceptionAction() {
                        public java.lang.Object run() throws Exception {
                            if( !nextField.isAccessible() ) {
                                nextField.setAccessible(true);
                            }
                            nextField.set(theInstance, value);
                            return null;
                        }
                    });
                }
            } catch(Throwable t) {
                IOException ioe = new IOException();
                Throwable cause = (t instanceof InvocationTargetException) ?
                    ((InvocationTargetException)t).getCause() : t;
                ioe.initCause( cause );
                throw ioe;
            }
        }
    
private static java.lang.ClassgenerateAndLoad(com.sun.ejb.codegen.ClassGeneratorFactory cgf, java.lang.String actualClassName, java.lang.ClassLoader loader, java.lang.Class protectionDomainBase)


        cgf.evaluate();

        final Properties props = new Properties();
        if( _logger.isLoggable(Level.FINE) ) {

            props.put(DUMP_AFTER_SETUP_VISITOR, "true");
            props.put(TRACE_BYTE_CODE_GENERATION, "true");
            props.put(USE_ASM_VERIFIER, "true");

            try {

                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                PrintStream ps = new PrintStream(baos);

                _sourceCode(ps, props);
                _logger.fine(baos.toString());

            } catch(Exception e) {
                _logger.log(Level.FINE, "exception generating src", e);
            }

        }
        
        Class result = null;
        try {
            if(System.getSecurityManager() == null) {
                result = _generate(loader, protectionDomainBase.getProtectionDomain(), 
                        props);
            } else {
                result = (Class)  java.security.AccessController.doPrivileged
                        (new java.security.PrivilegedAction() {
                    public java.lang.Object run() {
                        return _generate(loader, 
                                protectionDomainBase.getProtectionDomain(), props);
                    }});
            }
        } catch (RuntimeException runEx) {
            //We would have got this exception if there were two (or more)
            //  concurrent threads that attempted to define the same class
            //  Lets try to load the class and if we are able to load it
            //  then we can ignore the exception. Else throw the original exception
            try {
                result = loader.loadClass(actualClassName);
                _logger.log(Level.FINE, "[EJBUtils] Got exception ex: " + runEx
                        + " but loaded class: " + result.getName());
            } catch (ClassNotFoundException cnfEx) {
                throw runEx;
            }
        }
        
        return result;
    
private static java.lang.ClassLoadergetBusinessIntfClassLoader(java.lang.String businessInterface)

        
        ClassLoader contextLoader = null;
        if(System.getSecurityManager() == null) {
            ClassLoader cl = Thread.currentThread().getContextClassLoader();
            contextLoader = (cl != null) ? cl :
                ClassLoader.getSystemClassLoader();
        } else {
            contextLoader = (ClassLoader)
            java.security.AccessController.doPrivileged
                    (new java.security.PrivilegedAction() {
                public java.lang.Object run() {
                    // Return context class loader.  If there is none,
                    // which could happen within Appclient container,
                    // return system class loader.
                    ClassLoader cl =
                            Thread.currentThread().getContextClassLoader();
                    return (cl != null) ? cl :
                        ClassLoader.getSystemClassLoader();
                    
                }});
        }

        final Class businessInterfaceClass = 
            contextLoader.loadClass(businessInterface);
        
        ClassLoader appClassLoader = null;
        if(System.getSecurityManager() == null) {
            appClassLoader = businessInterfaceClass.getClassLoader();
        } else {
            appClassLoader = (ClassLoader)
            java.security.AccessController.doPrivileged
                    (new java.security.PrivilegedAction() {
                public java.lang.Object run() {
                    return businessInterfaceClass.getClassLoader();
                    
                }});
        }

        return appClassLoader;
    
private static java.lang.StringgetClassPackageName(java.lang.String intf)

        int dot = intf.lastIndexOf('.");
        return (dot == -1) ? null : intf.substring(0, dot);
    
private static java.lang.StringgetClassSimpleName(java.lang.String intf)

        int dot = intf.lastIndexOf('.");
        return (dot == -1) ? intf : intf.substring(dot+1);
    
public static java.lang.StringgetGeneratedRemoteIntfName(java.lang.String businessIntf)

        String packageName = getClassPackageName(businessIntf);
        String simpleName = getClassSimpleName(businessIntf);
        String generatedSimpleName = "_" + simpleName + "_Remote";
        return (packageName != null) ? 
            packageName + "." + generatedSimpleName : generatedSimpleName;
    
public static java.lang.StringgetGeneratedRemoteWrapperName(java.lang.String businessIntf)

        String packageName = getClassPackageName(businessIntf);
        String simpleName = getClassSimpleName(businessIntf);
        String generatedSimpleName = "_" + simpleName + "_Wrapper";
        return (packageName != null) ? 
            packageName + "." + generatedSimpleName : generatedSimpleName;
    
public static java.lang.StringgetGeneratedSerializableClassName(java.lang.String beanClass)

        String packageName = getClassPackageName(beanClass);
        String simpleName = getClassSimpleName(beanClass);
        String generatedSimpleName = "_" + simpleName + "_Serializable";
        return (packageName != null) ? 
            packageName + "." + generatedSimpleName : generatedSimpleName;
    
public static java.lang.StringgetGenericEJBHomeClassName()

        return "com.sun.ejb.codegen.GenericEJBHome_Generated";
    
public static java.lang.StringgetRemote30HomeJndiName(java.lang.String jndiName)

        return jndiName + REMOTE30_HOME_JNDI_SUFFIX;
    
public static java.lang.StringgetRemoteEjbJndiName(com.sun.enterprise.deployment.EjbReferenceDescriptor refDesc)
Actual jndi-name under which Remote ejb factory depends on whether it's a Remote Home view or Remote Business view. This is necessary since a single session bean can expose both views and the resulting factory objects are different. These semantics are not exposed to the developer-view to keep things simpler. The developer can simply deal with a single physical jndi-name. If the target bean exposes both a Remote Home view and a Remote Business view, the developer can still use the single physical jndi-name to resolve remote ejb-refs, and we will handle the distinction internally. Of course, this is based on the assumption that the internal name is generated in a way that will not clash with a separate top-level physical jndi-name chosen by the developer. Note that it's better to delay this final jndi name translation as much as possible and do it right before the NamingManager lookup, as opposed to changing the jndi-name within the descriptor objects themselves. This way, the extra indirection will not be exposed if the descriptors are written out and they won't complicate any jndi-name equality logic.


        return getRemoteEjbJndiName(refDesc.isEJB30ClientView(),
                                    refDesc.getEjbInterface(),
                                    refDesc.getJndiName());
    
public static java.lang.StringgetRemoteEjbJndiName(boolean businessView, java.lang.String interfaceName, java.lang.String jndiName)


        String returnValue = jndiName;

        if( businessView ) {
            if( jndiName.startsWith(CORBA_INS_PREFIX) ) {
                
                // In the case of a corba interoperable naming string, we
                // need to lookup the internal remote home.  We can't rely
                // on our SerialContext Reference object
                // (com.sun.ejb.containers.RemoteBusinessObjectFactory)
                // to do the home lookup because we have to directly access
                // the CosNaming service.
                returnValue = getRemote30HomeJndiName(jndiName);

            } else {
                if( !jndiName.endsWith("#" + interfaceName) ) {
                    returnValue = jndiName + "#" + interfaceName;
                }
            }
        }

        return returnValue;
    
private static java.util.CollectiongetSerializationFields(java.lang.Class clazz)


        Field[] fields = clazz.getDeclaredFields();

        SortedMap<String, Field> sortedMap = new TreeMap<String, Field>();

        for(Field next : fields) {

            int modifiers = next.getModifiers();
            if( Modifier.isStatic(modifiers) || 
                Modifier.isTransient(modifiers) ) {
                continue;
            }

            // All fields come from a single class(not from any superclasses),
            // so sorting on field name is sufficient.  We use natural ordering
            // of field name java.lang.String object.
            sortedMap.put(next.getName(), next);

        }

        return (Collection<Field>) sortedMap.values();
    
private static booleanisEJB30Ref(com.sun.enterprise.deployment.EjbReferenceDescriptor refDesc)

        return refDesc.isEJB30ClientView();
    
public static booleanisEjbRefCacheable(com.sun.enterprise.deployment.EjbReferenceDescriptor refDesc)


        // 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 ( (!isEJB30Ref(refDesc)) && 
                 (refDesc.getEjbDescriptor() != null) );
    
public static java.lang.ClassloadGeneratedGenericEJBHomeClass(java.lang.ClassLoader appClassLoader)


        String className = getGenericEJBHomeClassName();

        Class generatedGenericEJBHomeClass = null;
        
        try {
            generatedGenericEJBHomeClass = appClassLoader.loadClass(className);
        } catch(Exception e) {
        }
        
        if( generatedGenericEJBHomeClass == null ) {
            
            GenericHomeGenerator gen =new GenericHomeGenerator(appClassLoader);
                

            generatedGenericEJBHomeClass =generateAndLoad(gen, className,
                    appClassLoader, EJBUtils.class);
        }

        return generatedGenericEJBHomeClass;
    
public static voidloadGeneratedRemoteBusinessClasses(java.lang.String businessInterfaceName)


        ClassLoader appClassLoader = 
            getBusinessIntfClassLoader(businessInterfaceName);
        
        loadGeneratedRemoteBusinessClasses(appClassLoader, 
                                           businessInterfaceName);
    
public static voidloadGeneratedRemoteBusinessClasses(java.lang.ClassLoader appClassLoader, java.lang.String businessInterfaceName)


        String generatedRemoteIntfName = EJBUtils.
            getGeneratedRemoteIntfName(businessInterfaceName);
        
        String wrapperClassName = EJBUtils.
            getGeneratedRemoteWrapperName(businessInterfaceName);

        Class generatedRemoteIntf = null;
        try {
            generatedRemoteIntf = 
                appClassLoader.loadClass(generatedRemoteIntfName);
        } catch(Exception e) {
        }
        
        Class generatedRemoteWrapper = null;
        try {
            generatedRemoteWrapper = 
                appClassLoader.loadClass(wrapperClassName);
        } catch(Exception e) {
        }
        
        if( (generatedRemoteIntf != null) && 
            (generatedRemoteWrapper != null) ) {
            return;
        }

        _setClassLoader(appClassLoader);

        if( generatedRemoteIntf == null ) {
            
            RemoteGenerator gen = new RemoteGenerator(appClassLoader,
                                                      businessInterfaceName);

            Class developerClass = appClassLoader.loadClass(businessInterfaceName);
            generatedRemoteIntf = generateAndLoad(gen, generatedRemoteIntfName,
                    appClassLoader, developerClass);

        }

        if( generatedRemoteWrapper == null ) {
            
            Remote30WrapperGenerator gen = new Remote30WrapperGenerator
                (appClassLoader, businessInterfaceName, 
                 generatedRemoteIntfName);
                                      
            Class developerClass = appClassLoader.loadClass(businessInterfaceName);
            generatedRemoteWrapper = generateAndLoad(gen, wrapperClassName,
                    appClassLoader, developerClass);
        }

    
public static java.lang.ClassloadGeneratedSerializableClass(java.lang.ClassLoader appClassLoader, java.lang.String developerClassName)


        String generatedSerializableClassName = 
            getGeneratedSerializableClassName(developerClassName);
            

        Class generatedSerializableClass = null;
        try {
            generatedSerializableClass = 
                appClassLoader.loadClass(generatedSerializableClassName);

        } catch(Exception e) {
        }
        
        if( generatedSerializableClass == null ) {
            
            SerializableBeanGenerator gen = 
                new SerializableBeanGenerator(appClassLoader,
                                              developerClassName);

            Class developerClass = appClassLoader.loadClass(developerClassName);
            generatedSerializableClass = generateAndLoad(gen, generatedSerializableClassName,
                    appClassLoader, developerClass);

        }

        return generatedSerializableClass;
    
public static java.lang.ObjectlookupRemote30BusinessObject(java.lang.Object jndiObj, java.lang.String businessInterface)

        Object returnObject = null;

        try {
            
            ClassLoader loader = 
                getBusinessIntfClassLoader(businessInterface);
            
            Class genericEJBHome = loadGeneratedGenericEJBHomeClass
                (loader);
            
            final Object genericHomeObj =
                PortableRemoteObject.narrow(jndiObj, genericEJBHome);
            
            // The generated remote business interface and the
            // client wrapper for the business interface are produced
            // dynamically.  The following call must be made before
            // any EJB 3.0 Remote business interface runtime behavior
            // is needed in a given JVM.  
            loadGeneratedRemoteBusinessClasses(businessInterface);
            
            String generatedRemoteIntfName = EJBUtils.
                getGeneratedRemoteIntfName(businessInterface);
            
            Method createMethod = genericEJBHome.getMethod
                ("create", String.class);
            
            final java.rmi.Remote delegate = (java.rmi.Remote) 
                createMethod.invoke(genericHomeObj, 
                                    generatedRemoteIntfName);
            
            returnObject = createRemoteBusinessObject
                (loader, businessInterface, delegate);
            
        } catch(Exception e) {
            NamingException ne = new NamingException
                ("ejb ref resolution error for remote business interface" 
                 + businessInterface);
            
            ne.initCause(e instanceof InvocationTargetException ?
                         e.getCause() : e);
            throw ne;
        }

        return returnObject;
               
    
public static java.lang.ObjectresolveEjbRefObject(com.sun.enterprise.deployment.EjbReferenceDescriptor refDesc, java.lang.Object jndiObj)


        Object returnObject = jndiObj;

        if( refDesc.isLocal() ) {

            EjbDescriptor target = refDesc.getEjbDescriptor();
            ContainerFactory cf = Switch.getSwitch().getContainerFactory();
            BaseContainer container = (BaseContainer) 
                cf.getContainer(target.getUniqueId());

            if( refDesc.isEJB30ClientView() ) {
                GenericEJBLocalHome genericLocalHome = 
                    container.getEJBLocalBusinessHome();
                returnObject = genericLocalHome.create(refDesc.getEjbInterface());
            } else {
                returnObject = container.getEJBLocalHome();
            }

        } else {

            // For the Remote case, the only time we have to do 
            // something extra with the given jndiObj is if the lookup 
            // is for a Remote 3.0 object and it was made through a
            // corba interoperable name.  In that case,
            // the jndiObj refers to the internal Remote 3.0 Home so we
            // still need to create a remote 30 client wrapper object.

            if ( refDesc.isEJB30ClientView() &&
                 !(jndiObj instanceof RemoteBusinessWrapperBase) ) {
                returnObject = EJBUtils.lookupRemote30BusinessObject
                    (jndiObj, refDesc.getEjbInterface());
            }

        }

        return returnObject;

    
public static final byte[]serializeObject(java.lang.Object obj, boolean replaceObject)
Utility methods for serializing EJBs, primary keys and container-managed fields, all of which may include Remote EJB references, Local refs, JNDI Contexts etc which are not Serializable. This is not used for normal RMI-IIOP serialization. It has boolean replaceObject control, whether to call replaceObject or not


                                                          
          
                                                
	     
    
        return IOUtils.serializeObject(obj, replaceObject);
    
public static final byte[]serializeObject(java.lang.Object obj)

        return IOUtils.serializeObject(obj, true);
    
public static voidserializeObjectFields(java.lang.Class clazz, java.lang.Object instance, java.io.ObjectOutputStream oos)


        final ObjectOutputStream objOutStream = oos;

        // Write out list of fields eligible for serialization in sorted order.
        for(Field next : getSerializationFields(clazz)) {

            final Field nextField = next;
            final Object theInstance = instance;
            try {
                Object value = null;
                if(System.getSecurityManager() == null) {
                    if( !nextField.isAccessible() ) {
                        nextField.setAccessible(true);
                    }
                    value = nextField.get(theInstance);
                } else {
                    value = java.security.AccessController.doPrivileged(
                            new java.security.PrivilegedExceptionAction() {
                        public java.lang.Object run() throws Exception {
                            if( !nextField.isAccessible() ) {
                                nextField.setAccessible(true);
                            }
                            return nextField.get(theInstance);
                        }
                    });
                }
                objOutStream.writeObject(value);
            } catch(Throwable t) {
                IOException ioe = new IOException();
                Throwable cause = (t instanceof InvocationTargetException) ?
                    ((InvocationTargetException)t).getCause() : t;
                ioe.initCause( cause );
                throw ioe;
            }
        }
    
public static booleanuseStaticCodegen()

        synchronized (EJBUtils.class) {
            if( ejbUseStaticCodegen_ == null ) {
                String ejbStaticCodegenProp = null;
                if(System.getSecurityManager() == null) {
                    ejbStaticCodegenProp = 
                        System.getProperty(EJB_USE_STATIC_CODEGEN_PROP);
                } else {
                    ejbStaticCodegenProp = (String)
                    java.security.AccessController.doPrivileged
                            (new java.security.PrivilegedAction() {
                        public java.lang.Object run() {
                            return 
                                System.getProperty(EJB_USE_STATIC_CODEGEN_PROP);
                        }});
                }
                      
                boolean useStaticCodegen = 
                    ( (ejbStaticCodegenProp != null) &&
                      ejbStaticCodegenProp.equalsIgnoreCase("true"));
                
                ejbUseStaticCodegen_ = new Boolean(useStaticCodegen);

                _logger.log(Level.FINE, "EJB Static codegen is " +
                            (useStaticCodegen ? "ENABLED" : "DISABLED") +
                            " ejbUseStaticCodegenProp = " + 
                            ejbStaticCodegenProp);
            }
        }

        return ejbUseStaticCodegen_.booleanValue();