/*
* BEGIN_HEADER - DO NOT EDIT
*
* The contents of this file are subject to the terms
* of the Common Development and Distribution License
* (the "License"). You may not use this file except
* in compliance with the License.
*
* You can obtain a copy of the license at
* https://open-esb.dev.java.net/public/CDDLv1.0.html.
* See the License for the specific language governing
* permissions and limitations under the License.
*
* When distributing Covered Code, include this CDDL
* HEADER in each file and include the License file at
* https://open-esb.dev.java.net/public/CDDLv1.0.html.
* If applicable add the following below this CDDL HEADER,
* with the fields enclosed by brackets "[]" replaced with
* your own identifying information: Portions Copyright
* [year] [name of copyright owner]
*/
/*
* @(#)SunASJBIBootstrap.java
* Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
*
* END_HEADER - DO NOT EDIT
*/
package com.sun.jbi.framework.sun;
import com.sun.appserv.server.LifecycleEvent;
import com.sun.appserv.server.LifecycleEventContext;
import com.sun.appserv.server.LifecycleListener;
import com.sun.appserv.server.ServerLifecycleException;
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
/**
* This is the bootstrap class for the JBI runtime framework. It implements the
* Sun AppServer <CODE>LifecycleListener</CODE> interface and is responsible
* for creating the class loader hierarchy required by the JBI runtime. It also
* acts as a pass-through to the top-level class of the JBI runtime framework,
* <CODE>SunASJBIFramework</CODE>, which also implements the
* <CODE>LifecycleListener</CODE> interface and is responsible for all of the
* actual processing of the events from the AppServer.
*
* The only method required by the <CODE>LifecycleListener</CODE> interface is
* <CODE>handleEvent()</CODE>, which handles AppServer events for initialization,
* startup, ready, shutdown, and termination. In this bootstrap class, the only
* event of interest is the initialization event. When this event is received
* the class loaders for the JBI runtime framework are created, and then the
* <CODE>SunASJBIFramework</CODE> class is loaded, an instance of the class is
* created, and a reference to that instance is saved. All events, including
* initialization, are passed through to the <CODE>handleEvent()</CODE> method
* of that instance.
*
* This class is configured in the domain.xml file for the AppServer using the
* following XML:
*
* <PRE><CODE>
* <applications>
* <lifecycle-module name="JBIFramework"
* class-name="com.sun.jbi.framework.sun.SunASJBIBootstrap"
* classpath="full path to jar file containing JBI classes"
* enabled="true"
* is-failure-fatal="false">
* <property name="property name" value="property value">
* ....
* </lifecycle-module>
* </applications>
* </CODE></PRE>
*
* @author Sun Microsystems, Inc.
*/
public class SunASJBIBootstrap
implements LifecycleListener
{
/**
* Instance of the Sun AS JBI Framework life cycle class.
*/
private LifecycleListener mFramework;
/**
* Class loader for the JSR208 interfaces.
*/
private URLClassLoader mJbiClassLoader;
/**
* Class loader for the JBI runtime framework.
*/
private URLClassLoader mRuntimeClassLoader;
/**
* Name of the property defining the jbi home directory.
*/
private static final String JBI_HOME_PROPERTY = "com.sun.jbi.home";
/**
* Name of the jbi lib directory under jbi home.
*/
private static final String JBI_LIB = "lib";
/**
* Name of the jar file containing the JSR208-defined interfaces.
*/
private static final String JBI_JAR_NAME = "jbi.jar";
/**
* Name of the jar file containing JBI runtime interfaces accessible to
* some components.
*/
private static final String JBI_EXT_JAR_NAME = "jbi-ext.jar";
/**
* Name of the jar file containing the JBI runtime implementation.
*/
private static final String JBI_FRAMEWORK_JAR_NAME = "jbi_framework.jar";
/**
* Name of the top-level class of the JBI runtime framework.
*/
private static final String JBI_FRAMEWORK_CLASS_NAME =
"com.sun.jbi.framework.sun.SunASJBIFramework";
/**
* Provide the special processing for the AppServer lifecycle initialization
* event. When this event is received, create the class loaders for the JBI
* runtime framework, load the top-level class (<CODE>SunASJBIFramework</CODE>),
* create a new instance of that class and save a reference to it.
* For all events, call the <CODE>handleEvent()</CODE> method of that class,
* passing in the event that was received from the AppServer.
* @param anEvent LifecycleEvent from AppServer
* @throws ServerLifecycleException if any error occurs processing
* an event.
*/
public void handleEvent(LifecycleEvent anEvent)
throws ServerLifecycleException
{
// This entire method must be enclosed in a try-catch block to
// prevent any exception other than ServerLifecycleException from
// being thrown. Any other exception causes the AppServer startup
// to fail. Note that there is no need to log the exceptions here,
// as GlassFish logs them.
try
{
// This is the first event presented by the AppServer. Set up the
// JBI runtime class loaders, load the top-level class, create an
// instance of it, and save a reference to that instance.
if ( LifecycleEvent.INIT_EVENT == anEvent.getEventType() )
{
setUpClassLoaders((Properties) anEvent.getData());
mFramework = getJBIFramework();
}
// All events are passed through to the JBI runtime top-level class
// for the real processing.
mFramework.handleEvent(anEvent);
}
catch ( ServerLifecycleException slEx )
{
throw slEx;
}
catch ( Throwable ex )
{
throw new ServerLifecycleException(ex);
}
}
/**
* Private method that sets up the class loader hierarchy for the JBI
* runtime. Two classloaders are created, one for all of the JSR208-defined
* interfaces, and one for the JBI runtime implementation. The reason for
* separate class loaders for these two sets of classes is that the JBI
* runtime implementation must be isolated from being accessed directly by
* installed components. Furthermore, both components and the JBI runtime
* must have access to the JSR208 interfaces through the same class loader.
*
* These class loaders are set up as follows:
*
* - The JSR208 class loader has the AppServer's common class loader as its
* parent
* - The JBI runtime class loader has the JSR208 class loader as its parent.
*
* For information on the AppServer class loader hierarchy:
*
* @see http://docs.sun.com/source/819-0079/dgdeploy.html#wp58491
*
* @param ctxProperties the properties received from the Appserver in the
* LifecycleEvent.
* @throws MalformedURLException If the URL to any jar file is invalid.
* @throws SecurityException If access to a class loader was denied.
*/
private void setUpClassLoaders(Properties ctxProperties)
throws Exception, java.net.MalformedURLException
{
ArrayList jarFiles;
URL[] jarURLs;
String jbiRoot = ctxProperties.getProperty(JBI_HOME_PROPERTY);
String jarRoot = jbiRoot + File.separator + JBI_LIB;
// Create the class loader for the JSR208 interfaces. The parent of
// this class loader is the Appserver's common class loader.
jarFiles = new ArrayList();
jarFiles.add(jarRoot + File.separator + JBI_JAR_NAME);
jarFiles.add(jarRoot + File.separator + JBI_EXT_JAR_NAME);
jarURLs = list2URLArray(jarFiles);
mJbiClassLoader = new URLClassLoader(jarURLs,
this.getClass().getClassLoader().getParent().getParent());
// Create the class loader for JBI runtime. The parent of this class
// loader is the JSR208 interface class loader.
jarFiles = new ArrayList();
jarFiles.add(jarRoot + File.separator + JBI_FRAMEWORK_JAR_NAME);
jarURLs = list2URLArray(jarFiles);
mRuntimeClassLoader = new URLClassLoader(jarURLs, mJbiClassLoader);
}
/**
* Private method to convert a List into a URL array.
*
* @param paths list of String elements representing paths and JAR file
* names
* @return java.net.URL[] array representing the URLs corresponding to the
* paths, or null if the list is null or if there is an exception creating
* the array.
* @throws MalformedURLException If any URL is invalid.
*/
private URL[] list2URLArray (List paths)
throws java.net.MalformedURLException
{
File f;
URL[] urls = new URL[paths.size()];
int i = 0;
for ( Iterator itr = paths.listIterator(); itr.hasNext(); )
{
String nextCPElement = (String) itr.next();
f = new File(nextCPElement);
urls[i++] = f.toURL();
}
return urls;
}
/**
* Private method to load the top-level class of the JBI runtime framework,
* create an instance of it, and return a reference to that instance.
*
* @return an instance of the top-level runtime class.
* @throws ServerLifecycleException If the class cannot be loaded.
*/
private LifecycleListener getJBIFramework()
throws ServerLifecycleException
{
Object o;
try
{
o = mRuntimeClassLoader.loadClass(JBI_FRAMEWORK_CLASS_NAME).
newInstance();
}
catch ( ClassNotFoundException cnfEx )
{
throw new ServerLifecycleException(cnfEx);
}
catch ( IllegalAccessException iaEx )
{
throw new ServerLifecycleException(iaEx);
}
catch ( InstantiationException inEx )
{
throw new ServerLifecycleException(inEx);
}
return (LifecycleListener) o;
}
}
|