Package com.sun.enterprise.ee.server

Source Code of com.sun.enterprise.ee.server.AppLoaderEventListener

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package com.sun.enterprise.ee.server;

import com.sun.enterprise.server.*;
import com.sun.enterprise.config.ConfigContext;
import com.sun.enterprise.config.serverbeans.Applications;
import com.sun.enterprise.config.serverbeans.J2eeApplication;
import com.sun.enterprise.config.serverbeans.ServerBeansFactory;
import com.sun.enterprise.ee.server.group.Barrier;
import com.sun.enterprise.ee.server.group.Message;
import com.sun.enterprise.ee.server.group.core.ServerMessageRuntime;
import com.sun.enterprise.loader.EJBClassPathUtils;
import com.sun.enterprise.server.ApplicationServer;
import com.sun.enterprise.server.ServerContext;
import com.sun.enterprise.server.ApplicationLoadEventListener;
import com.sun.enterprise.server.event.ApplicationEvent;
import com.sun.enterprise.server.event.EarLifecycleListener;
import com.sun.enterprise.server.event.EjbContainerEvent;
import com.sun.enterprise.tools.verifier.tests.app.EARFileUsesClassPath;
import com.sun.logging.LogDomains;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
* ApplicationLoaderEventListener implementation. This is the basic entry
* point for Ear Lifecycle notification.
*
* @author Binod.
*/
public class AppLoaderEventListener implements EarLifecycleListener {

    private static final String LISTENER = "EAR-Loader-Listener";
    private static Logger __logger = LogDomains.getLogger(LogDomains.LOADER_LOGGER);   
    ServerMessageRuntime smrt = null;
    static long timeout = 1000 * 30;
    static final String EARLCTIMEOUT = "com.sun.enterprise.loaderevent.timeout";
    static {
        try {
            String strTimeout = System.getProperty(EARLCTIMEOUT);
            if (strTimeout != null)
                timeout = Long.valueOf(strTimeout).longValue();
        }catch (Exception e) {           
             __logger.log(Level.SEVERE, e.getMessage(), e);
        }
    }
   
    public void handleEvent(ApplicationEvent event) {
       
        // There is only one instance of AppLoaderEventListener. So, in essence,
        // smrt is a singleton.
        // FIX ME: May be create this lazily?
        if (smrt == null)
            smrt = ServerMessageRuntime.create(LISTENER, __logger);
       
        if (event.getEventType() == ApplicationEvent.AFTER_APPLICATION_LOAD) {
            ApplicationLoadEventListener loaderListener = __handleEvent(event);
            String appName = event.getApplication().getRegistrationName();
            if (loaderListener != null) {
                MessageCallBackImpl impl =
                new MessageCallBackImpl(loaderListener);
                impl.setLoading(true);

                ClassLoader toSet = loaderListener.getClass().getClassLoader();
                ClassLoader saved = setContextClassLoader(toSet);
                // Invoke the per-instance listener.
                loaderListener.handleLoad();
                setContextClassLoader(saved);
               
                //During load, aggregate the results. So, all the instances
                //will send the notification to the elected instnace. So, the
                //route is ALLTOONE.
                Barrier b = getServerMessageRuntime().initiateMessaging(appName,
                Message.Route.ALLTOONE,impl);
               
                if (b != null)
                    b.start(timeout);
            }
           
            return;
        }   
       
        if (event.getEventType() == ApplicationEvent.BEFORE_APPLICATION_UNLOAD){                  
            ApplicationLoadEventListener loaderListener = __handleEvent(event);
            String appName = event.getApplication().getRegistrationName();
            if (loaderListener != null) {
                MessageCallBackImpl impl =
                new MessageCallBackImpl(loaderListener);
                // In case of unload, an ONETOALL message should be sent so that
                // all instances will wait for clusterwide uload to complete.
                // FIX ME. Would ALLTOONE be better here also?
                getServerMessageRuntime().initiateMessagingAndWait(appName,
                Message.Route.ONETOALL,impl);               

                ClassLoader toSet = loaderListener.getClass().getClassLoader();
                ClassLoader saved = setContextClassLoader(toSet);
                loaderListener.handleUnLoad();
                setContextClassLoader(saved);

                //Lets make sure that message runtime doesnt keep this app any more.
                getServerMessageRuntime().purge(appName);
            }
            return;
        }  
       
        if (event.getEventType() == ApplicationEvent.APPLICATION_LOADFAIL) {
            ApplicationLoadEventListener loaderListener = __handleEvent(event);
            String appName = event.getApplication().getRegistrationName();
            if (loaderListener != null) {
                MessageCallBackImpl impl =
                new MessageCallBackImpl(loaderListener);
                impl.setFailure(true);

                ClassLoader toSet = loaderListener.getClass().getClassLoader();
                ClassLoader saved = setContextClassLoader(toSet);
                // Invoke the per-instance listener.
                loaderListener.handleLoadFailure();           
                setContextClassLoader(saved);
           
                //ALLTOONE message to aggregate failure messages.
                Barrier b = getServerMessageRuntime().initiateMessaging
                (appName+"__fail", Message.Route.ALLTOONE, impl);
               
                if (b != null)
                    b.start(timeout);               
            }
            return;
        }   
    }
 

    ServerMessageRuntime getServerMessageRuntime() {    
        return smrt;
    }
   
    private ApplicationLoadEventListener __handleEvent(ApplicationEvent event) {
        String appName = event.getApplication().getRegistrationName();
        ConfigContext ctx = event.getConfigContext();
        if (ctx == null) {
            ctx = ApplicationServer.getServerContext().getConfigContext();
        }
        Applications apps = null;
        try {
            apps = ServerBeansFactory.getApplicationsBean(ctx);               
        } catch (Exception e) {
            return null;
        }
        J2eeApplication app = apps.getJ2eeApplicationByName(appName);
           
        if (app == null )
            return null;
           
        if (__logger.isLoggable(Level.FINE)) {
            __logger.fine("The application load event for  "  + appName);
        }
           
        String loc = app.getLocation();
           
        //Try to retrieve the loader listener classname from manifest.
        Manifest mf = EJBClassPathUtils.getManifest(loc);

        String loaderListener = null;
        if (mf != null) {
            Attributes ars = mf.getMainAttributes();
            if (ars != null) {
                loaderListener = ars.getValue(LISTENER);
            }
        }
                       
        if (loaderListener == null) {
            if (__logger.isLoggable(Level.FINE)) {
                __logger.fine("Loader Listener is null for" + appName);
            }
            return null;
        }
           
        if (__logger.isLoggable(Level.FINE)) {
            __logger.fine("Loader Listener is available for " + appName);
        }
           
        Object listenerObject = null;
        try {               
            listenerObject = event.getApplication().getClassLoader().
            loadClass(loaderListener).newInstance();
        } catch (Exception e) {
            __logger.log(Level.WARNING, e.getMessage(), e);
            return null;
        }
         
           
        return ApplicationLoadEventListener.class.cast(listenerObject);
           
    }


    /**
     * Utility method for setting the context classloader.
     */
    static ClassLoader setContextClassLoader(ClassLoader newClassLoader) {

        // Can reference only final local variables from dopriveleged block
        final ClassLoader classLoaderToSet = newClassLoader;

        final Thread currentThread = Thread.currentThread();
        ClassLoader originalClassLoader = currentThread.getContextClassLoader();

        if (classLoaderToSet != originalClassLoader) {
            if (System.getSecurityManager() == null) {
                currentThread.setContextClassLoader(classLoaderToSet);
            } else {
                java.security.AccessController.doPrivileged(
                        new java.security.PrivilegedAction() {
                            public java.lang.Object run() {
                                currentThread.setContextClassLoader
                                (classLoaderToSet);
                                return null;
                            }
                        }
                );
            }
        }
        return originalClassLoader;
    }

}
TOP

Related Classes of com.sun.enterprise.ee.server.AppLoaderEventListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.