/********************************************************************************** * $URL: https://source.sakaiproject.org/svn/mailarchive/trunk/mailarchive-james/james/src/java/org/sakaiproject/james/PhoenixLauncherMain.java $ * $Id: PhoenixLauncherMain.java 105079 2012-02-24 23:08:11Z ottenhoff@longsight.com $ *********************************************************************************** * * Copyright (c) 2003, 2004, 2005, 2006, 2008 The Sakai Foundation * * Licensed under the Educational Community License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.opensource.org/licenses/ECL-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * **********************************************************************************/ package org.sakaiproject.james; import java.io.File; import java.lang.reflect.Method; import java.net.URL; import java.security.CodeSource; import java.security.PermissionCollection; import java.security.Permissions; import java.security.Policy; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.StringTokenizer; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** Taken from the phoenix 4.0.4 org.apache.avalon.phoenix.launcher.Main.java */ /* * Copyright (C) The Apache Software Foundation. All rights reserved. This software is published under the terms of the Apache Software License version 1.1, a copy of which has been included with this distribution in the LICENSE.txt file. */ /** * PhoenixLoader is the class that bootstraps and sets up engine ClassLoader. It also sets up a default policy that gives full permissions to engine code. * * @author <a href="mailto:peter at apache.org">Peter Donald</a> */ public final class PhoenixLauncherMain { /** Our logger. */ private static Log M_log = LogFactory.getLog(PhoenixLauncherMain.class); private static final String MAIN_CLASS = "org.apache.avalon.phoenix.frontends.CLIMain"; private static final String LOADER_JAR = "phoenix-loader.jar"; private static Object c_frontend; /** * Main entry point for Phoenix. * * @param args * the command line arguments * @throws Exception * if an error occurs */ public static final void main(final String[] args) throws Exception { final int exitCode = startup(args, new HashMap(), true); System.exit(exitCode); } /** * Method to call to startup Phoenix from an external (calling) application. Protected to allow access from DaemonLauncher. * * @param args * the command line arg array * @param data * a set of extra parameters to pass to embeddor * @param blocking * false if the current thread is expected to return. * @return the exit code which should be used to exit the JVM * @throws Exception * if an error occurs */ protected static final int startup(final String[] args, final Map data, final boolean blocking) throws Exception { int exitCode; try { // setup new Policy manager // TODO: (done) removed // Policy.setPolicy( new FreeNEasyPolicy() ); // Create engine ClassLoader // TODO: (done) removed // final URL[] urls = getEngineClassPath(); // final URLClassLoader classLoader = new URLClassLoader( urls ); // TODO: add these extra paths to the existing classloader final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); // TODO: (done) use the one classloader // data.put( "common.classloader", ClassLoader.getSystemClassLoader() ); data.put("common.classloader", classLoader); data.put("container.classloader", classLoader); data.put("phoenix.home", new File(findPhoenixHome())); // Setup context classloader // TODO: (done) removed // Thread.currentThread().setContextClassLoader( classLoader ); // Create main launcher final Class clazz = classLoader.loadClass(MAIN_CLASS); final Class[] paramTypes = new Class[] { args.getClass(), Map.class, Boolean.TYPE }; final Method method = clazz.getMethod("main", paramTypes); c_frontend = clazz.newInstance(); // kick the tires and light the fires.... final Integer integer = (Integer) method.invoke(c_frontend, new Object[] { args, data, Boolean.valueOf(blocking) }); exitCode = integer.intValue(); } catch (final Exception e) { // TODO: (done) changed to a log // e.printStackTrace(); M_log.warn("PhoenixLauncherMain.startup: " + e); exitCode = 1; } return exitCode; } /** * Method to call to shutdown Phoenix from an external (calling) application. Protected to allow access from DaemonLauncher. */ protected static final void shutdown() { if (null == c_frontend) { return; } try { final Class clazz = c_frontend.getClass(); final Method method = clazz.getMethod("shutdown", new Class[0]); // Lets put this sucker to sleep method.invoke(c_frontend, new Object[0]); } catch (final Exception e) { // TODO: (done) changed to a log // e.printStackTrace(); M_log.warn("PhoenixLauncherMain.shutdown: " + e); } finally { c_frontend = null; } } /** * Create a ClassPath for the engine. * * @return the set of URLs that engine uses to load * @throws Exception * if unable to aquire classpath */ private static URL[] getEngineClassPath() throws Exception { final ArrayList urls = new ArrayList(); final File dir = findEngineLibDir(); final File[] files = dir.listFiles(); for (int i = 0; i < files.length; i++) { final File file = files[i]; if (file.getName().endsWith(".jar")) { urls.add(file.toURL()); } } // TODO: (done) add also the phoenix libs final File dir_p = findPhoenixLibDir(); final File[] files_p = dir_p.listFiles(); for (int i = 0; i < files_p.length; i++) { final File file = files_p[i]; if (file.getName().endsWith(".jar")) { urls.add(file.toURL()); } } return (URL[]) urls.toArray(new URL[urls.size()]); } /** * Find directory to load engine specific libraries from. * * @return the lib dir * @throws Exception * if unable to aquire directory */ private static File findEngineLibDir() throws Exception { final String phoenixHome = findPhoenixHome(); final String engineLibDir = phoenixHome + File.separator + "bin" + File.separator + "lib"; final File dir = new File(engineLibDir).getCanonicalFile(); if (!dir.exists()) { throw new Exception("Unable to locate engine lib directory at " + engineLibDir); } return dir; } /** * TODO: (done) added this method Find directory to load phoenix libraries from. * * @return the lib dir * @throws Exception * if unable to aquire directory */ private static File findPhoenixLibDir() throws Exception { final String phoenixHome = findPhoenixHome(); final String engineLibDir = phoenixHome + File.separator + "lib"; final File dir = new File(engineLibDir).getCanonicalFile(); if (!dir.exists()) { throw new Exception("Unable to locate engine lib directory at " + engineLibDir); } return dir; } /** * Utility method to find the home directory of Phoenix and make sure system property is set to it. * * @return the location of phoenix directory * @throws Exception * if unable to locate directory */ private static String findPhoenixHome() throws Exception { String phoenixHome = System.getProperty("phoenix.home", null); if (null == phoenixHome) { final File loaderDir = findLoaderDir(); phoenixHome = loaderDir.getAbsoluteFile().getParentFile() + File.separator; } phoenixHome = (new File(phoenixHome)).getCanonicalFile().toString(); System.setProperty("phoenix.home", phoenixHome); return phoenixHome; } /** * Finds the LOADER_JAR file in the classpath. */ private static final File findLoaderDir() throws Exception { final String classpath = System.getProperty("java.class.path"); final String pathSeparator = System.getProperty("path.separator"); final StringTokenizer tokenizer = new StringTokenizer(classpath, pathSeparator); while (tokenizer.hasMoreTokens()) { final String element = tokenizer.nextToken(); if (element.endsWith(LOADER_JAR)) { File file = (new File(element)).getCanonicalFile(); file = file.getParentFile(); return file; } } throw new Exception("Unable to locate " + LOADER_JAR + " in classpath"); } /** * Default polic class to give every code base all permssions. Will be replaced once the kernel loads. */ private static class FreeNEasyPolicy extends Policy { public PermissionCollection getPermissions(final CodeSource codeSource) { final Permissions permissions = new Permissions(); permissions.add(new java.security.AllPermission()); return permissions; } public void refresh() { } } }